【JS】解析JS事件流:穿越DOM的奇妙之旅

前言

最近也是马上面临着春招的浪潮,各位肯定会面临很多的面试,那么JS事件流也是一个面试常考题,希望本文能帮助大家彻底弄清楚JS事件流究竟是个什么东西?

什么是事件流

简单来说 JavaScript事件流描述了在页面中触发和处理事件的顺序。当用户与页面交互时(例如点击按钮、移动鼠标等),浏览器会生成相应的事件,并将其传递给适当的元素。JS事件流分为三个阶段

  1. 捕获阶段:在window上往事件触发处传播(捕获过程),遇到注册的 捕获 事件会触发。
  2. 目标阶段:到达事件触发处。
  3. 冒泡阶段:从事件触发处往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 事件流有所帮助,并能够在实际项目中得到应用。

相关推荐
咖啡の猫2 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲4 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5815 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路5 小时前
GeoTools 读取影像元数据
前端
ssshooter5 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友5 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry6 小时前
Jetpack Compose 中的状态
前端
dae bal7 小时前
关于RSA和AES加密
前端·vue.js
柳杉7 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog7 小时前
低端设备加载webp ANR
前端·算法