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

相关推荐
肥肠可耐的西西公主22 分钟前
前端(AJAX)学习笔记(CLASS 2):图书管理案例以及图片上传
前端·笔记·学习
大胖丫24 分钟前
vue 学习-vite api.js
开发语言·前端·javascript
孙桂月25 分钟前
ES6相关操作(2)
前端·javascript·es6
遇见很ok25 分钟前
js中 ES6 新特性详解
开发语言·javascript·es6
陈浩源同学26 分钟前
学习 TypeScript 栈和队列数据结构
前端·算法
天天开发26 分钟前
【零代码革命】用Trae打造Flutter应用:AI助力,小白秒变工程师-页面调教篇
前端
我这一生如履薄冰~27 分钟前
简单封装一个websocket构造函数
前端·javascript·websocket
fangcaojushi28 分钟前
解决webpack5.54打包图片及图标的问题
前端·vue.js
海盗强28 分钟前
Webpack打包优化
前端·webpack·node.js
星之卡比*30 分钟前
前端面试题---vite和webpack的区别
前端·面试