1. 事件委托
机制
事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。
假设,你的列表里有100个列表项。现在需要去监听点击的列表项时哪一个,如果给每一个列表项都添加监听函数,那么就有100个事件处理程序,会占用大量内存。
利用事件的冒泡机制,列表项的点击事件后续会冒泡到列表,可以给列表设置一个监听程序去捕获该次点击事件。列表监听到事件之后,只需要检查event对象的id属性就可以确认点击的列表项时哪一个。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8">
</head>
<body>
<script>
onload = function() {
document.getElementById('dir').addEventListener('click', event=>{
console.log(event.target);
})
}
</script>
<div>
<ul id="dir">
<li>东</li>
<li>南</li>
<li>西</li>
<li>北</li>
</ul>
</div>
</body>
</html>
2. 事件流
顺便写一点关于事件流的。
事件流描述了页面接收事件的顺序。
事件冒泡,事件从最具体的元素开始触发,然后向上层传播。
事件捕获,事件从文档树的最上层开始触发,然后向文档树的下层传播。
DOM事件流分为3个阶段:事件捕获、到达目标和事件冒泡。
事件捕获先发生,在捕获阶段可以拦截事件。然后实际的目标元素接收到事件。然后在由底向上冒泡。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8">
</head>
<body>
<script>
onload = function() {
let twindow = window;
let tdocument = document;
let tbody = document.body;
let inner = document.getElementById("inner");
inner.addEventListener('click', ()=>{
console.log('inner 冒泡');
}, false);
inner.addEventListener('click', ()=>{
console.log('inner 捕获');
}, true);
tbody.addEventListener('click', ()=>{
console.log('tbody 冒泡');
}, false);
tbody.addEventListener('click', ()=>{
console.log('tbody 捕获');
}, true);
tdocument.addEventListener('click', ()=>{
console.log('tdocument 冒泡');
}, false);
tdocument.addEventListener('click', ()=>{
console.log('tdocument 捕获');
}, true);
twindow.addEventListener('click', ()=>{
console.log('twindow 冒泡');
}, false);
twindow.addEventListener('click', ()=>{
console.log('twindow 捕获');
}, true);
}
</script>
<div id="inner" style="width: 100px; height: 100px; background-color: aquamarine;">
</div>
</body>
</html>
点击结果为:
可以很清楚的看到事件先由外层的window捕获,然后向内传播,inner接收到之后,再向外层冒泡。