移动端的touch事件处理
WebApp
chemzqm
1人收藏 258次学习

移动端的touch事件处理

 

简要的探讨一下移动端 touch 事件处理几个坑,以及相应的简单处理方法。

click 穿透

假设有个弹出层,上面有个关闭的按钮支持 touchend 触发后关闭,若正好下方有个元素支持 click 事件,在弹出层关闭后将会在下方元素触发 click 事件。这种效果肯定不是我们需要的,而且我们无法确定合适会在上方出现一个支持 touch 的弹出层,所以我认为最好的处理方式是禁用所有元素的 click 事件,相比 click 需要长达 1s 的触发时间,使用 touchend 可以获得更好的体验。

tap 事件的判定

一个正确的 tap 事件应当满足一下条件:

  1. 用户手指从屏幕移开时触发
  2. 不能在用户移动手指时触发(防止和滚动、拖拽事件的冲突)
  3. 多个手指同时触摸屏幕时不能触发
  4. 不应该触发 click 事件

具体实现代码可以参考 tap-event

使用原生的滚动事件

Android 4.0 以下是不支持原生的 webview 滚动的,所以只能使用 iscroll 之类的工具来模拟元素滚动。它的缺点就是有些过于的复杂,所以我还是会在条件允许的情况下使用原生的滚动。

启用原生滚动只需要给外层元素加上样式 -webkit-overflow-scrolling: touch; 即可,如果你的监听函数比较占用资源我们可以通过一个简单的 buffer 函数来限制它的触发间隔,例如:

function buffer(fn, ms) {
  var timeout;
  return function() {
    if (timeout) return;
    var args = arguments;
    timeout = setTimeout(function() {
      timeout = null;
      fn.apply(null, args);
    }, ms);
  }
}


document.querySelector('.scrollable').onscroll = buffer(onScroll, 100);

另外的建议就是不要在可滚动元素上使用阴影样式(text-shadow 和 box-shadow),因为它们非常影响性能,而且看上去也不怎么美观。

还有需要注意的是如果你需要启用apple-mobile-web-app-capable, 注意将apple-mobile-web-app-status-bar-style设置为black-translucent,否则会出现还差 22 像素滚动不到头的坑爹 bug。

禁用页面整体拖动

IOS下默认情况下用户的拖动操作在scroll滚到头以后会导致整体页面的滚动,一种方式是禁用掉 document 的 touchmove 原生触发

document.addEventListener('touchmove', function(e) {
  e.preventDefault();
});

此时原生的滚动是无法工作的,解决办法就是禁用滚动元素的 touchmove 事件冒泡

scrollable.addEventListener('touchmove', function (e) {
   e.stopPropagation();
});

另一种方式是判定滚动元素滚到头之后禁用掉默认的处理

var el = document.querySelector('.scrollable');
var sy = 0;
events.bind(el, 'touchstart', function (e) {
  sy = e.pageY;
})

events.bind(el, 'touchmove', function (e) {
  var down = (e.pageY - sy > 0);
  //top
  if (down && el.scrollTop <= 0) {
    e.preventDefault();
  }
  //bottom
  if (!down && el.scrollTop >= el.scrollHeight - el.clientHeight) {
    e.preventDefault();
  }
})

我个人倾向于第二种方案,因为如果单纯的禁用 document 的 touchmove 监听,会导致一些处理的失效,比如说上面提到的 tap-event 模块。

 

 

 

拖动方向与距离

通过 event 的 pageX 和 pageY 属性即可计算,可参考 hammer.js

原文地址:移动端的touch事件处理

加入1KE学习俱乐部

1KE学习俱乐部是只针对1KE学员开放的私人俱乐部