移动端在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);

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

  1. 移动端的传统click事件延迟和点透现象

    一.场景描述: 1.A/B两个层上下z轴重叠. 2.上层的A点击后消失或移开.(这一点很重要) 3.B元素本身有默认click事件(如a标签) 或 B绑定了click事件. 在以上情况下,点击A/B重 ...

  2. jquery关于on click事件的理解

    jquery关于on click事件的理解 <pre><a style="min-width:60px; margin-left:6px;" wenzhangid ...

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

    这两天在做一个WAP页面,在chrome上模拟移动端的时候,都好好的,然而放到手机上测试时, 发现有些点击事件直接无反应,但是有些有反应: 难道是由于我页面上有用到滚动插件,里面的touch事件的pr ...

  4. 重载jquery on方法实现click事件在移动端的快速响应

    额,这个标题取的还真是挺装的... 其实我想表达的是jquery click事件如何在移动端自动转换成touchstart事件. 因为移动端click事件会比touchstart事件慢几拍 移动设备某 ...

  5. 移动端tap或touch类型事件的点透问题认识

    1.什么是点透? 举例说明:下图B元素是黄色方块,B元素中包含了C元素,C元素是一个a链接,本身自带click事件按,然后又一个半透明的粉色元素A遮盖在B元素上(看图中A元素是覆盖在B元素上的,不然B ...

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

    在移动端 触屏click事件虽然也会响应,但是总感觉是有延迟,一直听说click事件在手机上有200~300毫秒的延迟问题,亲自测了一下,在pc端模拟手机的话是测不出来的,但是用手机测试时发现延迟非常 ...

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

    对于前端工程师来说,apicloud无疑给我们提供了很好的平台,有各种各样的模块供我们使用,但是在实际项目的时候,很大部分的代码,还是需要我们用html css js来实现的.但是呢,移动端页面对于c ...

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

    这两天自己在写一个手机网页,用到了触屏滑动的特效,就是往右滑动的时候左侧隐藏的菜单从左边划出来. 做完之后在手机原生浏览器中运行正常,但在QQ和微信中打开,发现touchmove只会触发一次,而且to ...

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

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...

随机推荐

  1. Struts2 输入校验(使用编码方式)

    一.Struts输入校验 1.创建register.jsp <%@ page language="java" contentType="text/html; cha ...

  2. Spring Boot-JPA、Hibernate、Spring data jpa之间的关系

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

  3. 解决:Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceMode

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Eric_K1m/article/deta ...

  4. Deepin系统中手动开启swap的方法

    Deepin系统中手动开启swap的方法 如何设置 swap(交换空间)的大小建议设置和你的实际物理内存一样大,如你的内存是8G的,则可将下面的count的值设为8192(当然这只是参考值,你可根据你 ...

  5. 使用JSP的fmt标签实现国际化支持 - smart-framework ; smart-plugin-i18n

    使用JSP的fmt标签实现国际化支持   Smart-framework框架使用smart-plugin-i18n插件来完成国际化处理,原理相同,使用过滤器进行参数设置. ============== ...

  6. odoo开发笔记 -- 单台物理服务器上,利用docker部署多套odoo应用

    部署结构: 待更新! ----服务器硬件配置: 操作系统:ubuntu16.04-64bit CPU/内存:4核8G 1. 基础环境安装 nginx离线安装: docker环境安装: 2. 官方容器镜 ...

  7. Python3基础 from...import 局部导入

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  8. linux 系统应用程序桌面图标显示及自启动

    cp test.desktop $RPM_BUILD_ROOT/usr/share/applications/    桌面显示 cp test.desktop $RPM_BUILD_ROOT/etc/ ...

  9. [精] UBOOT2017+FIT 启动流程详尽分析

    开发环境:Nanopi-neo-plus2 软件版本:uboot-2017 软件版本:linux-4.14 买这个板子有一段时间了,并没有全身心的投入在上面,有时间了的话就搞一搞, 这篇随笔算是对这个 ...

  10. jquery预加载显示百分比

    jquery预加载显示百分比 <pre> <img class="bj loadimg" loadimg="/weiqingshu/images/1/b ...