移动端的touch click事件的理解+点透

移动端在touch上一共有4个事件

touchstart touchmove touchend touchcancel, touchcancel, 一般来说,它们执行的顺序为 touchstart -> touchmove -> touchend -> touchcancel . 其中touchcancel一般情况下不会触发,也不是这里讨论的焦点;

这里会结合click对上面的事件进行讨论, touch发生在click之前

先上段代码,直观感受一下

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      #level0 {
        /* width: 500px;
        height: 500px; */
      }

      #level1-0 {
        background: red;
        width: 500px;
        height: 500px;
      }

      #level1-1 {
        background: green;
        width: 500px;
        height: 500px;
      }
    </style>
  </head>
  <body>
    <div id="level0">
      <div id="level1-0">
      </div>
      <div id="level1-1">
      </div>
    </div>
  </body>
  <script type="text/javascript">

    var level10 = document.getElementById("level1-0");

    level10.addEventListener(‘touchstart‘, function(e) {
      console.log(1);
    });

    level10.addEventListener(‘touchmove‘, function(e) {
      console.log(2);
    });

    level10.addEventListener(‘touchend‘, function(e) {
      console.log(3);
    });

    level10.onclick = function() {
      console.log(5);
    }

    document.body.onclick = function() {
      console.log(‘6‘);
    }

  </script>
</html>

在红色区域点击会出现什么效果呢? 出现的是 1 3 5 6, 奇怪了 touchmove 为何不执行,因为我们并没有移动,也就是说,必须触碰到屏幕上面,而且发生了移动动作,touchmove才执行,现在我们触碰到,而且手指稍微动一下,发现输出的效果是, 1 2(+) 3, 其中touchmove 可能触发多次,又奇怪了, click为何不执行, 因为 click执行的条件是 点击, 而且不移动 所以一般情况下,我们可以理解成 touchmove和click是相斥的。

我们知道,当一个用户在点击屏幕的时候,系统会触发touch事件和click事件,touch事件优先处理,touch事件经过 捕获,处理, 冒泡 一系列流程处理完成后, 才回去触发click事件

既然touch事件和click事件有了优先级别,那么能不能在touch阶段取消掉系统触发的click事件呢?当然是可以的,浏览器提供了这样的能力。在touch事件里面,调用e.preventDefault() 就可以阻止本次点击系统触发的click事件,即本次相关的click都不会执行

把上面代码稍微加一点

level10.addEventListener(‘touchstart‘, function(e) {
      console.log(1);
      e.preventDefault();
});

点击的时候 发现 只有 1 3, 说明click被阻止了,当然在touchend里面加效果也一样,所以 在touch事件里面加 e.preventDefault可以取消系统产生的click事件, 当然不会阻止后面的touch事件。

用个具体的例子看看 如何解决点透问题

产生点透问题的原因, 可以先看看代码吧

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      #level0 {
        /* width: 500px;
        height: 500px; */
        position: relative;
      }

      #level1-0 {
        position: absolute;
        z-index: 1;
        background: red;
        width: 500px;
        height: 500px;
      }

      #level1-1 {
        background: green;
        width: 500px;
        height: 500px;
      }
    </style>
  </head>
  <body>
    <div id="level0">
      <div id="level1-0">
      </div>
      <div id="level1-1">
      </div>
    </div>
  </body>
  <script type="text/javascript">

    var level10 = document.getElementById("level1-0");
    var level11 = document.getElementById("level1-1");

    level10.addEventListener(‘touchstart‘, function(e) {
      level10.style.display = ‘none‘;
    });

    level11.onclick = function() {
      console.log(‘level11莫名被点击了‘);
    }

  </script
</html>

本来是 level1-0 和 level1-1是兄弟节点,即他们之间不会发生什么 事件传递, 目前level1-0相当于一个覆盖层,覆盖在level1-1上面, 按理说点击 level1-0的时候,level1-0会阻挡所有的事件,事件不会传递给level1-1,当点击level1-0的时候,实际上level1-1也发生了点击事件,即上面的输出结果为level1-0消失, 输出 level11莫名被点击了, 这就是点透

点透发生的条件:

  1. A 和 B不是后代继承关系(如果是后代继承关系的话,就直接是冒泡子类的话题了)
  2. A发生touch, A touch后立即消失, B事件绑定click
  3. A z-index大于B,即A显示在B浮层之上

点透发生的理由: 当手指触摸到屏幕的时候,系统生成两个事件,一个是touch 一个是click,touch先执行,touch执行完成后,A从文档树上面消失了,而且由于移动端click还有延迟200-300ms的关系,当系统要触发click的时候,发现在用户点击的位置上面,目前离用户最近的元素是B,所以就直接把click事件作用在B元素上面了.

那如何才能解决点透问题呢? 还记得我之前说过么,系统提供了先触发的touch事件去取消系统生成的click事件,所以只要在touch事件的某个处理函数中 执行 e.preverDefault即可, 一般我们在touchend中执行

在上面代码中,加上这句就完美解决了

level10.addEventListener(‘touchend‘, function(e) {
    e.preventDefault();
});

当然点透问题,还有其他的解决方法,关键是 要么是需求本次系统生成的click事件,要么是当系统触发click的时候,当前的触发touch的那个dom节点还存在。比如将其一延迟3s在关闭

setTimeout(() => {
        level10.style.display = ‘none‘;
}, 300);

原文地址:https://www.cnblogs.com/web-record/p/10280847.html

时间: 2024-11-07 17:37:10

移动端的touch click事件的理解+点透的相关文章

开发移动端web页面click事件失效问题

这两天在做一个WAP页面,在chrome上模拟移动端的时候,都好好的,然而放到手机上测试时, 发现有些点击事件直接无反应,但是有些有反应: 难道是由于我页面上有用到滚动插件,里面的touch事件的preventDefault导致click失效? 于是,换成了touchSart事件试了下,效果比之前略好,但是,有重复点击事件,本小白排查了一会儿, 发现页面上明明在滚动区域有别的点击事件,为毛别的用的好好的,就这个不行,仔细对比,发现别的都是A标签, 无效的是DIV,于是,我就像发现了新大陆一样,麻

移动端触屏click点击事件延迟问题,以及tap的解决方案

在移动端 触屏click事件虽然也会响应,但是总感觉是有延迟,一直听说click事件在手机上有200~300毫秒的延迟问题,亲自测了一下,在pc端模拟手机的话是测不出来的,但是用手机测试时发现延迟非常明显,用我的iphone5执行下段测试代码,平均延迟在370毫秒!结果非常惊人,所以在移动端必须得用tap事件了,click不仅仅是慢的问题,而且会严重影响css3动画!没错,这绝对是真的,我做的单页应用,用click事件执行的,点击后css3切换动画,经常会出现动画被省略掉直接到最后一个keyfr

分享一个移动项目中消除click事件点击延迟的方法

对于前端工程师来说,apicloud无疑给我们提供了很好的平台,有各种各样的模块供我们使用,但是在实际项目的时候,很大部分的代码,还是需要我们用html css js来实现的.但是呢,移动端页面对于click事件会有 300 毫秒的延迟,导致多数用户感觉移动设备上基于 HTML 的 web 应用界面响应速度慢. 在这里推荐一个简单易用的 js库,用来消除界面中的click事件造成的延迟. https://github.com/ftlabs/fastclick 目前,亲测在iphone表现很完美.

移动端WEB开发,click,touch,tap事件浅析

一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分别代表单次点击和双次点击. 二.关于tap的点透处理 在使用zepto框架的tap来移动设备浏览器内的点击事件,来规避click事件的延迟响应时,有可能出现点透的情况,即点击会触发非当前层的点击事件. 处理方式: (1). github上有一个叫做fastclick的库,它也能规避移动设备上clic

移动端开发用touch事件还是click事件

前端开发现在包含了跨浏览器,跨平台(不同操作系统)和跨设备(不同尺寸的设备)开发. 在移动开发的过程中,到底选取touch事件还是click事件?对了,请不要鄙视click,click在移动端开发用着也是不错的. 首先,我先说一下touch事件在开发中存在的两个问题: 1.touch事件在某些场景下存在点击穿透的问题. 2.touchstart事件时触摸屏幕就会触发,touchend事件是手指离开屏幕就会触发,而有时候,我们仅仅是只想滑动屏幕,却会触发这两个事件. 1问题的原因:移动端事件触发的

移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法

这两天自己在写一个手机网页,用到了触屏滑动的特效,就是往右滑动的时候左侧隐藏的菜单从左边划出来. 做完之后在手机原生浏览器中运行正常,但在QQ和微信中打开,发现touchmove只会触发一次,而且touchend也经常不触发. 之后百度了一下这个问题,原因是 主要是由于200ms超时导致内核不一定会一直处理touchmove事件,一旦超时会将后续所有的事件转交给UI处理,导致touchmove不会一直触发. 为了解决开发者需要,建议开发者在touchstart时调用event.preventDe

web开发,click,touch,tap事件浅析

一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分别代表单次点击和双次点击. 二.关于tap的点透处理 在使用zepto框架的tap来移动设备浏览器内的点击事件,来规避click事件的延迟响应时,有可能出现点透的情况,即点击会触发非当前层的点击事件. 处理方式: (1). github上有一个叫做fastclick的库,它也能规避移动设备上clic

百度地图JS API移动端,phonegap 自定义覆盖物Click事件无法执行 的 bug 解决方法

当你为自定义覆盖物添加了click事件后,你会发现在移动端是无论如何也触发不了的,这算是一个BUG. 最近我在为我的地图APP开发第二版,在为一个覆盖物添加行为事被困扰到了,自定义覆盖物的click事件竟然无法在iPhone端触发,以及百度地图JS API里面的开源库涉及到自定义覆盖物click事件的均无效. 我为这个BUG烦恼了很久,直到今天,在QQ群里网友(在此要先感谢这位网友mooring)告诉了我解决方法:iPhone上的自定义覆盖物事件默认会触发map的click事件,如果map定义了

移动端click事件延迟300ms的原因以及解决办法

这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题 —— 当时的网站都是为大屏幕设备所设计的.于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题.这当中最出名的,当属双击缩放(double tap to zoom).这也是会有上述 300 毫秒延迟的主要原因. 当用户一次点击屏幕之后,浏览器并不能立刻判断用户是要进行双击缩放,还是想要进行单击操作.因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕. 于是,