事件冒泡及阻止
当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window
,当然其传播的是事件,绑定的执行函数并不会传播,如果父级没有绑定事件函数,就算传递了事件,也不会有什么表现,但事件确实传递了。
事件冒泡的原因是事件源本身可能没有处理事件的能力,即处理事件的函数并未绑定在该事件源上。它本身并不能处理事件,所以需要将事件传播出去,从而能达到处理该事件的执行函数。
实例
当点击id
为i3
的<div>
时,浏览器会依次弹出3 2 1
,这就是事件冒泡,此正方形处于叶节点上,对其操作的事件会向上进行冒泡,直到根节点。
<!DOCTYPE html><html><head><title>JS事件冒泡及阻止</title></head><style type="text/css">div{display: flex;justify-content: center;align-items: center;}</style><body><div id="i1" style="height: 150px;width: 150px;background: red;"><div id="i2" style="height: 100px;width: 100px;background: green;"><div id="i3" style="height: 50px;width: 50px;background: blue;"></div></div></div></body><script type="text/javascript">document.getElementById("i1").addEventListener('click',(e) => {alert(1);}) document.getElementById("i2").addEventListener('click',(e) => {alert(2);}) document.getElementById("i3").addEventListener('click',(e) => {alert(3);})</script></html>
应用场景
例如我们有10
个<li>
标签,每个标签有一个uid
作为判断用户点击的区别,使用冒泡就不需要为每个<li>
绑定点击事件,可以称为事件委托。
<!DOCTYPE html><html><head><title>JS事件冒泡及阻止</title></head><style type="text/css">li{cursor: pointer;}</style><body><ul id="u1"><li uid="0">0</li><li uid="1">1</li><li uid="2">2</li><li uid="3">3</li><li uid="4">4</li><li uid="5">5</li><li uid="6">6</li><li uid="7">7</li><li uid="8">8</li><li uid="9">9</li></ul></body><script type="text/javascript">document.getElementById("u1").addEventListener('click',(e) => {alert(e.srcElement.getAttribute('uid'));}) </script></html>
阻止冒泡
有时候我们并不希望事件冒泡而去执行上级节点绑定的事件,这时候就需要阻止事件的冒泡,w3c
的方法是e.stopPropagation()
,IE
则是使用window.event.cancelBubble = true;
。
注意
不是所有的事件都能冒泡。以下事件不冒泡:blur
、focus
、load
、unload
。事件解决方案方式在不同浏览器,可能是有所区别的,有些不支持捕获型方案,多数浏览器默认冒泡型方案。阻止冒泡并不能阻止对象默认行为,例如submit
按钮被点击后会提交表单数据,需使用e.preventDefault();
阻止默认行为,IE
则是window.event.returnValue = false;
。每日一题
/WindrunnerMax/EveryDay