移动端的点击穿透
点击穿透
touch 事件结束后会默认触发元素的 click 事件,如没有设置完美视口,则事件触发的时间间隔为 300ms 左右,如设置完美视口则时间间隔为 30ms 左右(备注:具体的时间也看设备的特性)。
如果 touch 事件隐藏了元素,则 click 动作将作用到新的元素上,触发新元素的 click 事件或页面跳转,此现象称为点击穿透
解决方法一
阻止默认行为
//阻止默认行为
node.addEventListener('touchstart', function(e){
console.log('hello')
e.preventDefault();
})
解决方法二
使背后元素不具备click特性,用touchXxxx代替click
banner_img.addEventListener('touchstart',()=>{
locationbar.href('https://www.baidu.com')
})
解决方案三
让背后的元素暂时失去click事件,300毫秒左右再复原
#anode{
pointer-events: none;
}
btn.addEventListener('touchstart',(event)=>{
shade.style.display = 'none'
setTimeout(()=>{
anode.style.pointerEvents = 'auto'
},500)
})
解决方案四
让隐藏的元素延迟300毫秒左右再隐藏
btn.addEventListener('touchstart',(event)=>{
setTimeout(()=>{
shade.style.display = 'none'
},300)
})
关于页面跳转的选择
移动端页面跳转可以使用 a 链接,也可以使用 touchstart 事件来触发 JS 代码完成跳转
-
效率上,touchstart 速度更快
-
SEO 优化上, a 链接效果更好
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> * { margin: 0; padding: 0; } #demo { width: 100%; height: 200px; background-color: pink; } </style> </head> <body> <div id="demo"></div> <script> let time demo.addEventListener('touchstart', function() { console.log('手指触摸屏幕了') time = +new Date() }) demo.addEventListener('click', function() { console.log('点击了') console.log(new Date() - time) }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <title>Document</title> <style> * { margin: 0; padding: 0; } html, body, #app { width: 100%; height: 100%; } #app { position: relative; } #banner { width: 100%; height: 200px; background-color: orange; } #shade { position: absolute; text-align: center; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(1, 1, 1, 0.5); } h1 { margin-top: 100px; } /* a { pointer-events: none; */ /* } */ </style> </head> <body> <div id="app"> <a href="https://www.baidu.com" id="a"> <div id="banner"></div> </a> <div id="shade"> <h1>恭喜,一等奖</h1> <button id="btn">点击关闭</button> </div> </div> <script type="text/javascript"> const btn = document.getElementById('btn') const shade = document.getElementById('shade') btn.addEventListener('touchstart', e => { setTimeout(() => { shade.style.display = 'none' }, 500) // e.preventDefault() // setTimeout(() => { // a.style.pointerEvents = 'auto' // }, 500) }) // banner.addEventListener('touchstart', function() { // window.location.href = 'https://www.baidu.com' // }) </script> </body> </html>