什么是 click 点透
先上一段代码,直观感受一下
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>* {margin: 0;padding: 0;}.content {background: #ccc;height: 1200px;}.modal {position: absolute;top: 50%;left: 50%;width: 300px;height: 250px;background: #f30;transform: translate3d(-50%, -50%, 0);}</style></head><body><div id="app"><div id="js-content" class="content">我是内容 - B</div><div id="js-modal" class="modal">我是弹窗 - A</div></div><script>var $content = document.getElementById('js-content');var $modal = document.getElementById('js-modal');$modal.addEventListener('touchstart', function(e) {$modal.style.display = 'none';alert('$modal touchstart');});$modal.onclick = function() {alert('$modal click');}$content.onclick = function() {alert('$content click');}document.body.onclick = function() {alert('body click');}</script></body></html>
在手机上运行上面代码,会发现弹出的内容依次是:’modal touchstart’ > ‘content click’ > ‘body click’。会发现,明明点击的是弹出层,为什么会触发内容和body的click事件呢?
移动端浏览器要判断用户是否有进一步的操作[双击],touchstart 到 click执行会有延迟300ms。所以在触发弹窗A的touchstart后,期间会有延迟才执行click事件,但弹窗已经隐藏不现实,从而在同样位置执行click操作后,其实是在 content 内容B上执行。
点透出现的场景
刚才举例说明了什么是点透,其实点透的出现场景可以总结如下:
1、A/B两个层上下z轴重叠。
2、上层的A点击后消失或移开。(这一点很重要)
3、B元素本身有默认click事件(如a标签) 或 B绑定了click事件。
在以上情况下,点击A/B重叠的部分,就会出现点透的现象。
解决方案
1、对于B元素本身没有默认click事件的情况(无a标签等),应统一使用touch事件。
2、对于B元素本身存在默认click事件的情况,应取消A元素的默认点击事件,从而阻止click事件的产生。即应在上例的$modal touchstart监听事件中添加代码如下:
e.preventDefault();
3、在zepto修复问题之前,有fastclick、hammer等通用库可以使用。
其中最常使用的还是fastclick,地址 :https://github.com/ftlabs/fastclick
