文章目录
  1. 1. 背景
  2. 2. 过程
  3. 3. 解决办法
    1. 3.1. 解决办法一
    2. 3.2. 解决办法二

背景

讲讲今天遇到的这个bug,背景是我要做一个在移动端上上滑显示导航栏,下滑隐藏导航栏的效果,于是,我的基本思路是通过手机端的touchstarttouchend事件来计算手指触摸屏幕的横纵坐标,从而计算它的角度,用来判断是往上的方向还是往下的方向。

过程

嗯,想象很美好,于是,噼里啪啦地做好后,在苹果手机上一测,各种顺利通过,我对着手机会心一笑,需求完成。

然而,现实很残酷,产品经理跑来跟我说,安卓上的什么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事件,故没有效果。

解决办法

解决办法也不是没有的,先说明一下在移动端的事件:

  1. touchstart:手指触摸手机屏幕的触发,即使已经有一个手指放在屏幕上也会触发。
  2. touchmove:手指在手机屏幕时滑动时连续触发,发生期间,调用event.preventDefault()可以阻止滚动
  3. touchend;手机触摸屏幕离开后触发
  4. touchcancel:当系统停止跟踪触摸的时候触发

解决办法一

如果屏幕不考虑滚动的话,可以在touchstart中添加event.preventDefault(),意思是取消了touchstart的默认事件,但是这样做就没有了滚动手机屏幕这个效果,这个适用于局部使用。但我觉得这种效果并不好。

解决办法二

使用touchcancel事件,在js中同时绑定touchend和touchcancel事件,这里我截取了UC浏览器中的一段描述:

我认为这种办法是比较好的,当然这也不是最好的解决办法,拿来顶替一下还是可以的。

文章目录
  1. 1. 背景
  2. 2. 过程
  3. 3. 解决办法
    1. 3.1. 解决办法一
    2. 3.2. 解决办法二