再次总结移动端事【件穿穿透】问题
整体代码
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>vui</title>
</head>
<style>
#app {
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
z-index: 2;
background-color: red;
}
.dow {
width: 300px;
height: 300px;
position: absolute;
left: 0;
top: 0;
background-color: blue;
}
</style>
<body>
<div class="dow">
<div id=app>
</div>
</div>
<script >
let app = document.querySelector('#app')
let dow = document.querySelector('.dow')
// app.ontouchstart = function () {
// console.log('app click')
// }
app.addEventListener('touchstart', function (e) {
app.style.display = 'none'
console.log('app click')
e.preventDefault();
e.stopPropagation();
})
dow.addEventListener('click', function () {
console.log('dow click')
})
// touchstart 事件只能通过dom2方式 (也就是addEventListener传播)以下这种方式无响应的
// dow.ontouchstart = function () {
// console.log('dow click')
// }
</script>
</body>
</html>
事件穿透 不是 事件冒泡
1事件冒泡
事件冒泡存在的前提是层级嵌套
如: 这种情况下 两个元素都绑定click事件 或者touchstart事件,点击 app时 事件会冒泡到dow上
<div class="dow">
<div id=app>
</div>
</div>
如: 这种情况下 两个元素都绑定click事件 或者touchstart事件,点击 app时 事件不会冒泡
<div id=app>
</div>
<div class="dow">
</div>
总结: 由于body是所有dom的父层级,所以 任何事件都会冒泡到body上
2事件穿透
存在前提:
- 上层绑定 touchstart事件
- 下层绑定click事件
- 上层点击时候 隐藏自身
- 与两个元素是嵌套 还是 上下层 无关
产生原因: touchstart 先与click执行
解决方案:
app.addEventListener('touchstart', function (e) {
app.style.display = 'none'
console.log('app click')
//重点
e.preventDefault(); //组织事件默认事件,在事件touchstart时候就组织了继续往下产生click\touchend事件
e.stopPropagation();//非必须 此方法主要组织冒泡,由于前面结论可知,仅当dom存在嵌套下才会产生冒泡才需要此方法
})
"e.preventDefault(); //组织事件默认事件,在事件touchstart时候就组织了继续往下产生click\touchend事件" 的解释
<div class="dow">
<div id=app>
</div>
</div>
app.addEventListener('touchstart', function (e) {
app.style.display = 'none'
console.log('app touchstart')
e.preventDefault();
e.stopPropagation();
})
app.addEventListener('touchend', function (e) {
console.log('app end')
})
app.addEventListener('click', function (e) {
console.log('app click')
})
dow.addEventListener('touchstart', function () {
console.log('dow touchstart')
})
dow.addEventListener('click', function () {
console.log('dow click')
})
dow.addEventListener('touchend', function (e) {
console.log('dow touchend')
})
运行点击结果
- app touchstart
- app end
- dow touchend
翻译翻译
-对页面点击一次 会先后产生'touchstart' ----'touchend' ---- 'click'事件
我们对 app 绑定了 'touchstart' ----'touchend' ---- 'click' 并对 touchstart 绑定两个阻止方法
当我们点击app时候
产生 touchstart事件 ,由于对事件组织默认事件,所以接下来不会再产生click事件,也不会冒泡
产生 touchend事件 ,
冒泡 touchend事件 到dow上
补充两篇相关文章
- https://www.cnblogs.com/xiaoxingyiyi/p/5447378.html
- http://www.cnblogs.com/yexiaochai/p/3462657.html
最后的结论
移动端不建议用touch事件,弊端如代码只能在移动端使用,pc端无法使用,且ie内核可能无法兼容
用click事件 目前都用fastclick解决,其本质是在touchend事件中 触发click事件,并阻止默认的click事件,从而避免了300s延迟 和 事件 穿透