DOM事件流的三个阶段:
事件捕获阶段-->处于目标阶段-->事件冒泡阶段
addEventListener()的第三个参数为:true则表示将事件绑定在捕获阶段,false表示将事件绑定在冒泡阶段,默认为false
event.preventDefault() 阻止默认行为(如:a标签的默认行为 跳转链接、form表单的默认提交 submit、input输入keypress 等)
stopPropagation() 方法阻止捕获和冒泡阶段中当前事件的进一步传播。
举例说明
<body>
<div id="box1" style="width: 300px;height: 300px;background-color:#5500ff">
<div id="box2" style="width: 100px;height: 100px;background-color: #ED5250"></div>
</div>
</body>
document.addEventListener('click', () => {
console.log("我是document")
}, true)
document.getElementById("box1").addEventListener('click', () => {
console.log("我是box1")
}, true)
document.getElementById("box2").addEventListener('click', () => {
console.log("我是box2")
}, true)
如上,我们定义了三个捕获事件document、box1、box2
当我们单击box1则打印为
我是document
我是box1
说明:捕获阶段执行document的捕获事件,打印‘我是document’,然后向下搜索,遇到box1的捕获事件,此时为目标阶段,打印‘我是box1’,执行完后进入冒泡阶段,因为没有找到冒泡事件,所以执行结束。
当我们单击box2则打印为
我是document
我是box1
我是box2
说明:捕获阶段执行document的捕获事件,打印‘我是document’,然后向下搜索,遇到box1的捕获事件打印‘我是box1’,接着继续向下查找,到达box2元素,此时为目标阶段,打印‘我是box2’,最后进入冒泡阶段,因为没有找到冒泡事件,所以执行结束。
你可以理解为:只要响应一个事件,那么就会按照这个流程走:事件捕获阶段-->处于目标阶段-->事件冒泡阶段。
捕获阶段:整个页面所有的捕获事件,从document向下搜索执行,一直到目标元素,这期间所有的捕获事件都会执行。
目标阶段:当前目标元素的事件
冒泡阶段:目标元素事件执行完后,从当前元素向上冒泡执行所有的冒泡事件
如果我们将document事件改成冒泡事件,则代码为
document.addEventListener('click', () => {
console.log("我是document")
})
document.getElementById("box1").addEventListener('click', () => {
console.log("我是box1")
}, true)
document.getElementById("box2").addEventListener('click', () => {
console.log("我是box2")
}, true)
此时,
当我们单击box1则打印为: 我是box1 我是document
也就是捕获阶段没有,目标阶段打印‘我是box1’,最后冒泡阶段,打印‘我是document’
当我们单击box2则打印为: 我是box1 我是box2 我是document
也就是捕获阶段,先打印‘我是box1’,到目标阶段打印‘我是box2’,最后到冒泡阶段,打印‘我是document’
阻止事件传递:使用stopPropagation()
方法。
演示使用 stopPropagation
document.addEventListener('click', () => {
console.log("我是document")
})
document.getElementById("box1").addEventListener('click', (e) => {
e.stopPropagation()
console.log("我是box1")
}, true)
document.getElementById("box2").addEventListener('click', () => {
console.log("我是box2")
}, true)
如果在box1中增加stopPropagation(),则
当我们单击box1则打印为: 我是box1
也就是捕获阶段没有,目标阶段打印‘我是box1’,因为在这里有stopPropagation,则事件不再继续传递,下面就不执行了
当我们单击box2则打印为: 我是box1
也就是捕获阶段,先打印‘我是box1’,因为在这里有stopPropagation,则事件不再继续传递,下面就不执行了
关于addEventListener和stopPropagation的详细使用,请参考
https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopPropagation