【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 事件流有所帮助,并能够在实际项目中得到应用。

相关推荐
ConardLi8 分钟前
前端程序员原地失业?全面实测 Gemini 3.0,附三个免费使用方法!
前端·人工智能·后端
木子李BLOG44 分钟前
Element Plus
前端·javascript·vue.js
Miketutu1 小时前
【大屏优化秘籍】Element UI El-Table 表格透明化与自定义行样式实战
前端·javascript·vue.js
止水编程 water_proof1 小时前
JavaScript基础
开发语言·javascript·ecmascript
rainboy1 小时前
Flutter :自己动手,封装一个小巧精致的气泡弹窗库
前端·flutter·github
合作小小程序员小小店1 小时前
web网页开发,在线%人力资源管理%系统,基于Idea,html,css,jQuery,java,jsp,ssh,mysql。
java·前端·css·数据库·mysql·html·intellij-idea
Ace_31750887761 小时前
拼多多商品详情接口深度解析:从加密参数破解到数据全量获取
前端·数据库·github
yuejich2 小时前
命名规范snake_case
服务器·前端·数据库
天平2 小时前
开发了几个app后,我在React Native用到的几个库的推荐
android·前端·react native
消失的旧时光-19432 小时前
Kotlinx.serialization 对多态对象(sealed class )支持更好用
java·服务器·前端