1.第一种是 js 实现
通过 addEventListener 函数进行禁止,会监听自身以及所有子元素的事件
addEventListener(EventName,Funcction,Boolean)有三个参数:
EVentName:要监听的事件名称(如:鼠标点击事件【click】,鼠标按住事件【mousedown】)
Function:监听函数,参数 Event 对象
Boolean:监听事件传递方式,默认 false(false【冒泡传递】,true【捕获传递】)
冒泡传递:从子元素触发,接着传递到父元素触发
捕获传递:从父元素触发,接着转递到子元素触发
<div>
<span></span>
</div>
<script>
var dv = document.querySelector("div");var sn = document.querySelector("span");
dv.onclick = function(e){ console.log("div") };
sn.onclick = function(e){ console.log("span") };
</script>
如上代码所示 div 元素内包含 span 元素,div 有一个点事件,span有一个点击事件。
此时点击span,会发现控制台打印出两行,分别为 span、div,此时大家会很疑惑,为什么我点击是 span 元素,会打印出 div,这是因为事件是会传递的,并且默认冒泡传递,因为 div 元素有点击事件,所以 span 元素的点击事件触发后会传递到 div 元素,触发 div 元素的点击事件。反之我们点击 div 会发现控制台只打印出一行 div,此时div 点击事件触发后会传递给它的父元素 body,但是 body 元素没有事件,所以只打印一行 div。
那么如果想点击 span 的时候阻止触发 div 的点击事件,该怎么办呢?可以通过写一句 e.stopPropagation(); 来实现,它的作用是阻止事件传递。
// 把 sn.onclick = function(e){ console.log("span") };
// 改成以下内容
sn.onclick = function(e){ console.log("span");e.stopPropagation(); };
反过来点击 span 的时候怎么禁止 span 的点击事件呢?这时候 addEventListener 派上用场了,addEventListener的第三个参数很重要,可以将冒泡传递改为捕获传递,加上 e.stopPropagation(); 阻止事件传递。
// 把 dv.onclick = function(e){ console.log("div") };
// 改成以下内容
dv.addEventListener("click",function(e){console.log("div");e.stopPropagation();},true);
此时点击 span 元素会发现控制台只打印一行 div,而不会打印出 span 。这是为什么呢?因为 div 监听了点击事件,同时也监听了 span 的点击事件,且改为捕获传递,所以在点击 span 元素的时候,会先触发 div 的点击事件,然后再触发 span 的点击事件,但是在触发 div 的点击事件的时候,div 加上e.stopPropagation(); 阻止了事件传递,所以 span 的点击事件不会触发。可能网友会有疑惑为什么不用 dv.onclick 的方式,因为 dv.onclick 是一个函数,只能通过 e.stopPropagation() 阻止事件传递,并不能改变传递方式。
拓展:如何禁止页面的所有鼠标点击事件?
document.addEventListener("click",function(e){console.log("document");e.stopPropagation();},true);
注意:
1. dom.addEventListener 只能禁用 dom 自身包含的所有子元素事件触发,自身的事件不禁止的
2.只能禁止一类事件,如 dom.addEventListener("click") 只禁止所有子元素的鼠标点击事件,但禁用不了子元素的其他事件,比如鼠标按下事件(onmousedown),想要禁止鼠标按下事件,需再监听按下事件 dom.addEventListener("mousedown")。
2.第二种是 css 实现
通过给样式加上 pointer-events: none; 实现,作用是将元素虚拟化、透明化,将自身以及自身所有子元素的所有鼠标事件都不触发。
<style>
span{pointer-events: none;}
/* div{pointer-events: none;}*/
</style>
如跟上面一样点击 span 元素,禁止触发 span 的点击事件,给 span 或 div 的样式加上 pointer-events: none; 便可实现。给 span 加上时,只触发 div 的点击事件;给 div 加上时,都不会触发 div 和 span 的点击事件。
总结:
addEventListener 和 pointer-events 区别是前者不禁止自身的事件,只禁止所有子元素一类鼠标事件,需要禁止几类事件就必须监听几类事件,后者是禁止自身和所有子元素的所有鼠标事件