前言
最近也是马上面临着春招的浪潮,各位肯定会面临很多的面试,那么JS事件流也是一个面试常考题,希望本文能帮助大家彻底弄清楚JS事件流究竟是个什么东西?
什么是事件流
简单来说 JavaScript事件流描述了在页面中触发和处理事件的顺序。当用户与页面交互时(例如点击按钮、移动鼠标等),浏览器会生成相应的事件,并将其传递给适当的元素。JS事件流分为三个阶段:
- 捕获阶段:在window上往事件触发处传播(捕获过程),遇到注册的 捕获 事件会触发。
- 目标阶段:到达事件触发处。
- 冒泡阶段:从事件触发处往window上传播(冒泡过程),遇到注册的 冒泡 事件会触发。
相信大家仍然难以理解,我用一个实例给大家讲清楚:
在一个页面中,我放入一个嵌套了两层的盒子,并且每个盒子的背景颜色和大小不同以便区分。
xml
<style>
#app{
width: 400px;
height: 400px;
background-color: red;
}
#wrap{
width: 200px;
height: 200px;
background-color: green;
}
#box{
width: 100px;
height: 100px;
background-color: #000;
}
</style>
bash
<div id="app">
<div id="wrap">
<div id="box"></div>
</div>
</div>
然后我再添加分别给app、wrap、box盒子分别添加点击事件
xml
<script>
let app = document.getElementById('app');
let wrap = document.getElementById('wrap');
let box = document.getElementById('box');
app.addEventListener('click',(e) =>{
console.log('app');
})
box.addEventListener('click',(e) =>{
console.log('wrap');
})
box.addEventListener('click',(e) =>{
console.log('box');
})
</script>
点击一下box区域,会如何发生事件流的三个阶段,并且浏览器控制台打印的是什么? 我用一张图给大家展示一下:
所以很明显,js事件默认都在冒泡的过程中触发
补充
1. addEventListener的第三个参数:
该参数用来控制事件触发的阶段是捕获还是冒泡。是Boolean
类型,默认为false
,若我们改为true
,则事件都在捕获的过程中触发。
2. 阻止冒泡
1.方式:event.stopPropagation()
或者 event.stopImmediatePropagation()
。 其中event是事件参数。
2.两者区别:
event.stopPropagation()
- 这个方法用于阻止事件在DOM中进一步传播,但不会影响同一元素上的其他事件处理程序的执行。
- 如果在一个元素上绑定了多个事件处理程序,调用
stopPropagation()
只会阻止事件继续向上冒泡,不会影响其他处理程序的执行。
event.stopImmediatePropagation()
- 这个方法也用于阻止事件传播,但它不仅会停止事件继续传播,还会阻止同一元素上其他事件处理程序的执行。
- 即使同一个元素上有多个事件处理程序,只要其中一个调用了
stopImmediatePropagation()
,那么其他事件处理程序都不会被执行。
3. 事件委托
事件委托是一种利用事件冒泡机制来管理事件的技术。它的核心思想是将事件处理程序绑定在其父元素上 ,而不是直接绑定在每个子元素上。当子元素上的事件触发时,事件会冒泡至父元素,从而触发父元素上的事件处理程序。
事件委托的好处在于可以减少内存消耗和提高性能,特别是在处理大量相似元素的情况下。此外,它还可以简化代码,使代码更加清晰易懂。
例如下面的例子:
xml
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
document.getElementById('list').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('You clicked on ' + event.target.textContent);
}
});
</script>
在上面的示例中,我们将点击事件处理程序绑定在 ul
元素上,而不是每个 li
元素上。当用户点击列表项时,事件会冒泡至 ul
元素,从而触发事件处理程序,而不用去拿到每一个li
元素,那样太麻烦了!
最后
JavaScript 事件流是网页开发中不可或缺的一部分。通过深入理解事件流的概念和机制,我们可以编写更加高效和灵活的代码,实现丰富多彩的交互效果。希望本文对你理解 JavaScript 事件流有所帮助,并能够在实际项目中得到应用。