zoukankan      html  css  js  c++  java
  • 移动端tap与click的区别 && 点透事件

    移动端的问题

      移动端的主要问题是click会有300ms的延迟,主要原因是苹果手机在设计时,考虑到用户在浏览网页时需要放大,所以,在用户点击的300ms之后,才触发click,如果300ms之内还有click,就会进行放大缩小。 

      但是,问题是大部分时候放大、缩小时不需要的,有时开发者也会禁用他们,那么300ms的延迟就是性能上的损耗的,所以,如何解决这300ms的延迟? 在移动端,最容易想到的就是使用touchend来替代click,但是touchend是存在很大的问题的,因为touchend之前可能是touchstart、touchmove,最后才是touchstart,具体情境可能是用户滑动页面时,不小心在一个按钮那里触发了touchend,这样就执行了,但是用户的本意不是如此。 那么该怎么解决呢?

    tap事件

      为了减少这300ms的延迟,tap事件被很多框架(如zepto)封装,来减少这延迟问题, tap事件不是原生的,所以是封装的,那么具体是如何实现的呢?

      主要考虑到下面两点:

    • 按住的事件不能超过延时时间,因为长时间可能就是浏览器的复制、粘贴等操作了。
    • 不能在页面中移动,移动是不能触发tap事件的。 

      我们可以封装如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>tap</title>
      <meta name="viewport" content="width=device-width,initial-scale=1">
    </head>
    <body>
      <button id="btn">按钮</button>
      <script>
        function tap(ele, callback) {
          // 记录开始时间
          var startTime = 0,
          // 控制允许延迟的时间
              delayTime = 200,
          // 记录是否移动,如果移动,则不触发tap事件
              isMove = false;
    
          // 在touchstart时记录开始的时间
          ele.addEventListener('touchstart', function (e) {
            startTime = Date.now();
          });
    
          // 如果touchmove事件被触发,则isMove为true
          ele.addEventListener('touchmove', function (e) {
            isMove = true;
          });
    
          // 如果touchmove事件触发或者中间时间超过了延迟时间,则返回,否则,调用回调函数。
          ele.addEventListener('touchend', function (e) {
            if (isMove || (Date.now() - startTime > delayTime)) {
              return; 
            } else {
              callback(e);
            }
          })
        }
    
        var btn = document.getElementById('btn');
        tap(btn, function () {
          alert('taped');
        });
      </script>
    </body>
    </html>

      如上,我们就可以正常使用tap事件并且避免了300ms延迟的产生。

    点透问题

      如果我们在移动端所有的click都替换为了tap事件,还是会触发点透问题的,因为实质是: 在同一个z轴上,z-index不同的两个元素,上面的元素是一个绑定了tap事件的,下面是一个a标签,一旦tap触发,这个元素就会display: none,而从上面的tap可以看出,有touchstart、touchend,所以会300ms之后触发click事件,而z-index已经消失了,所以,触发了下面的a的click事件,注意: 我们认为a标签默认是绑定了click事件的。而这种现象不是我们所期待的。

      解决方案: (1)使用fastclick。 (2)添加一个延迟。

    (1)直接引入fastclick库。

    window.addEventListener("load", function () {
       FastClick.attach(document.body);
    }, false);

     这样,就可以成功解决问题了。

    (2)对于上一个tap做延迟。

    tap(ele, function () {
        setTimeout(function () {
           ele.style.display = 'none';
        }, 300); 
    })

      这样,过了300ms,那么click事件就不会触发在下面的a标签上了。

    一个人可以过孤独的生活,但一个人不可以过没有向往的生活。    --- 俞敏洪

  • 相关阅读:
    03 在百度地图上定位到指定位置
    01 如何将百度地图加入IOS应用程序?
    三个字理解委托机制
    iOS 应用程序打包、真机调试 方法
    在读iOS官方文档时,里面有很多你不懂的单词,不要担心
    用“大控件”与“大数据类型”思想来理解view Cotroller
    04 将当前位置用大头针标注到百度地图上
    02 使用百度地图获得当前位置的经纬度
    专注分享思考过程
    像孙正义为了练英语坚决不说日语一样。我也应该有坚决不看中文文档的心!
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/7588553.html
Copyright © 2011-2022 走看看