这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战
事件流
事件流是什么?
所谓事件流,就是当触发某个元素的事件时,事件会按照DOM树结构进行传播,传播的过程分为捕获阶段、目标阶段和冒泡阶段三个阶段。
1、捕获阶段:该阶段是由网景公司提出的。按照DOM树结构由document对象向下的顺序传播,直到目标元素为止。
2、目标阶段:该阶段就是指目标元素触发当前事件。
3、冒泡阶段:该阶段是由微软公司提出的,按照DOM树结构由目标元素向上的顺序传播,直到 document对象为止。
取消事件冒泡
当元素注册事件设置为冒泡阶段时,可以通过事件对象的stopPropagation()方法取消事件冒泡。
如下代码展示了事件流和取消事件冒泡的操作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件流</title>
<style>
#d1{
width: 200px;
height: 200px;
background-color: lightcoral;
padding: 50px;
}
#d2{
width: 100px;
height: 100px;
background-color: yellowgreen;
padding: 50px;
}
#d3{
width: 100px;
height: 100px;
background-color: aquamarine;
}
</style>
</head>
<body>
<div id="d1">
<div id="d2">
<div id="d3"></div>
</div>
</div>
<script>
var d1 = document.getElementById('d1');
d1.addEventListener('click',function () {
console.log('这是d1... ...')
},false);
var d2 = document.getElementById('d2');
d2.addEventListener('click',function () {
console.log('这是d2... ...')
},false);
var d3 = document.getElementById('d3');
d3.addEventListener('click',function (event) {
console.log('这是d3... ...');
// 取消冒泡阶段
event.stopPropagation();
},false);
</script>
</body>
</html>
效果图分析如下所示:
事件委托
当为大量的HTML元素注册相同事件,并且事件的句柄逻辑完全相同时,会造成页面速度下降。不过, 事件流允许在这些HTML元素的共同父级元素注册事件。这种方式被称为事件委托。
如下代码展示了使用事件委托解决代码重复的问题,但需要注意的是:场景不同,用法案例也不同。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
</head>
<body>
<div id="container">
<button id="btn1">按钮</button>
<button id="btn2">按钮</button>
<button id="btn3">按钮</button>
</div>
<script>
/* var btn1 = document.getElementById('btn1');
btn1.addEventListener('click',function () {
console.log('这是一个按钮');
});
var btn2 = document.getElementById('btn2');
btn2.addEventListener('click',function () {
console.log('这是一个按钮');
});
var btn3 = document.getElementById('btn3');
btn3.addEventListener('click',function () {
console.log('这是一个按钮');
});*/
// 不降事件绑定给指定元素,而是绑定给共同的父级/祖先元素
// 事件委托
var container = document.getElementById('container');
container.addEventListener('click',function (event) {
var target = event.target;
if (target.nodeName === 'BUTTON'){
console.log('这是一个按钮');
}
});
</script>
</body>
</html>