【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 小时前
基于HTML的悬窗可拖动记事本
前端·css·html
祝余呀2 小时前
html初学者第一天
前端·html
脑袋大大的3 小时前
JavaScript 性能优化实战:减少 DOM 操作引发的重排与重绘
开发语言·javascript·性能优化
速易达网络4 小时前
RuoYi、Vue CLI 和 uni-app 结合构建跨端全家桶方案
javascript·vue.js·低代码
耶啵奶膘5 小时前
uniapp+firstUI——上传视频组件fui-upload-video
前端·javascript·uni-app
JoJo_Way5 小时前
LeetCode三数之和-js题解
javascript·算法·leetcode
视频砖家5 小时前
移动端Html5播放器按钮变小的问题解决方法
前端·javascript·viewport功能
lyj1689976 小时前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
小白变怪兽7 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头7 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github