事件流
事件流描述的是从页面中接收事件的顺序。
【IE的事件流是事件冒泡流,Netscape的事件流是事件捕获流】
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
事件冒泡
事件冒泡即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
根据上述代码,单击页面中div元素,click事件会按如下顺序传播
事件捕获
根据上述代码,单击页面中div元素,click事件会按如下顺序传播
DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
【事件捕获 → 目标阶段 → 事件冒泡】
根据上述代码,单击页面中div元素,click事件会按如下顺序传播
事件委托
事件委托(事件代理),通过监听一个父元素,给不同的子元素绑定事件。
举个栗子:一个ul,ul里有100个li。若想给100个li都绑定事件,可以直接使用事件委托,给ul绑定事件,利用事件冒泡的规则来实现。
EventTarget.addEventListener()
target.addEventListener(type, listener, useCapture);
type:事件类型的字符串、listener:回调函数、useCapture:false(默认值:事件冒泡)、true(事件捕获)
一道面试题
<body>
<div id="div">
<ul class="ul">
<li class="li">test</li>
</ul>
</div>
<script>
document.getElementById("div").addEventListener("click", e => {
alert("div");
// e.stopPropagation(); {2}
},
// true {1}
);
document.querySelector(".ul").addEventListener("click", e => {
alert("ul");
});
document.querySelector(".li").addEventListener("click", e => {
alert("li");
});
</script>
</body>
- 点击test,依次弹出li、ul、div(事件冒泡)
- 若去掉第12行{1}的注释,依次弹出div、li、ul,第三个参数为true时代表事件捕获,先捕获后冒泡。
- 若再去掉第10行{2}的注释,只弹出div。event.stopPropagation()表示阻止捕获和冒泡阶段中当前事件进一步传播。
参考资料
- 《JavaScript高级程序设计》
- MDN:EventTarget.addEventListener()