安卓移动端滑动不支持touchend事件
背景
讲讲今天遇到的这个bug,背景是我要做一个在移动端上上滑显示导航栏,下滑隐藏导航栏的效果,于是,我的基本思路是通过手机端的touchstart
和touchend
事件来计算手指触摸屏幕的横纵坐标,从而计算它的角度,用来判断是往上的方向还是往下的方向。
过程
嗯,想象很美好,于是,噼里啪啦地做好后,在苹果手机上一测,各种顺利通过,我对着手机会心一笑,需求完成。
然而,现实很残酷,产品经理跑来跟我说,安卓上的什么UC浏览器,百度浏览器,对这个效果都不显示,QQ浏览器是一会显示,一会又傻傻的。
然后,我开始找问题,终于,发现在安卓上检测不出滑动时touchend事件的执行,问题找到了。于是我上网百度,到处一片哀怨,原来这个是安卓本身的bug,安卓的浏览器用的是所下载的浏览器本身的内核,所以各种类型的内核都有,上述几种浏览器都是有基于Tridient
来做的,简单来说,就是IE的内核,安卓一直在更新版本,却还是没有解决这个问题。相比之下,iphone就可爱很多,在iphone下的阿鸡阿狗浏览器,用的都是webkit
内核,对各种特性支持度都十分好,这就是差距啊!
在安卓上,滑动手机屏幕的触发事件过程是这样的:1
touchstart->touchmove*n,无touchend
在iphone上,滑动手机屏幕的触发事件过程是这样的:1
touchstart->touchmove*n->touchend
素以,在安卓上,滑动不能用touchend事件了(这里并不是说本身不能用touchend事件,只是滑动时无这个事件而已),经过查资料,发现之前很多人说zepto中的touch.JS在微信以及安卓上用swipe的时候失效,其实就是因为用了这个touchend事件,故没有效果。
解决办法
解决办法也不是没有的,先说明一下在移动端的事件:
- touchstart:手指触摸手机屏幕的触发,即使已经有一个手指放在屏幕上也会触发。
- touchmove:手指在手机屏幕时滑动时连续触发,发生期间,调用
event.preventDefault()
可以阻止滚动 - touchend;手机触摸屏幕离开后触发
- touchcancel:当系统停止跟踪触摸的时候触发
解决办法一
如果屏幕不考虑滚动的话,可以在touchstart中添加event.preventDefault()
,意思是取消了touchstart的默认事件,但是这样做就没有了滚动手机屏幕这个效果,这个适用于局部使用。但我觉得这种效果并不好。
解决办法二
使用touchcancel
事件,在js中同时绑定touchend和touchcancel事件,这里我截取了UC浏览器中的一段描述:
我认为这种办法是比较好的,当然这也不是最好的解决办法,拿来顶替一下还是可以的。