zoukankan      html  css  js  c++  java
  • 移动端的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),因为它们非常影响性能,而且看上去也不怎么美观。

    禁用页面整体拖动

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

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

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

    events.bind(scrollable, '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

  • 相关阅读:
    JS一些概念知识及参考链接
    CSS中浮动属性float及清除浮动
    前端一些概念知识及参考链接
    CSS中属性百分比的基准点
    CSS中的单位
    css居中问题
    Vue使用的扩展
    vue使用中的问题总结
    CSS中的position属性
    CSS中的flex布局
  • 原文地址:https://www.cnblogs.com/zjx2011/p/4864086.html
Copyright © 2011-2022 走看看