面试题:事件触发过程是什么样的?

浅聊一下

试想一下,我们有三个div,每个div上有一个点击事件,点击最大的div会输出app,点击中间的div会输出wrap,点击最小的div会输出box。那么当我们点击分别点击每一个图层时会输出什么呢?本篇文章将带大家来深入分析一下事件的触发过程...

事件的触发过程

捕获过程

事件触发的第一个过程是捕获过程,在window上往事件触发处传播,遇到注册的捕获事件会触发(从外往内传播)

  • 点击app

点击app,会从window开始往里找,第一步就找到了app,于是输出app

  • 点击wrap

点击wrap,会从window开始往里找,先找到app,再找到wrap,那么我们的输出结果应该是app->wrap 但是结果真的是这样吗?不是, 输出结果为wrap->app

为什么会发生这种情况呢??? 因为在监听器中除了点击事件,触发方法,还有一个可选的参数,参数为布尔值,默认为false

如果第三个参数为true,那么在捕获事件过程捕获到的事件就会触发,如果为false,也就是默认,那就是在冒泡过程触发,所以在这里我们在冒泡过程触发事件,先输出wrap再输出app

js 复制代码
     app.addEventListener('click',(e)=>{//绑定 注册 订阅
        console.log('app');
        e.stopImmediatePropagation()
     },false)
  • 点击box 根据上面两个例子,我们很容易就知道,这里输出顺序为box->wrap->app

那我们来看看什么是冒泡过程

冒泡过程

冒泡过程就是在我们找到目标子容器以后,再向父容器传递的一个过程,也就是捕获事件相反的方向, 从事件触发处往window上传播,遇到注册的冒泡事件会触发

f

event.stopPropagation() || e.stopImmediatePropagation()

如果我只想要我点击的那个容器触发,其他容器不触发,那应该怎么办呢?那么我们就得用到event.stopPropagation()或e.stopImmediatePropagation()了

这两个方法都是用来阻止默认事件的传播(用在冒泡就阻止冒泡,捕获就阻止捕获)

js 复制代码
        let box = document.getElementById('box')
        box.addEventListener('mouseenter',(e)=>{
            console.log('box');
            //  e.stopPropagation()//停止传播
            e.stopImmediatePropagation()
            
        })

此时,我们点击box,就只会打印box

那么这两个方法有什么区别呢?

js 复制代码
        let box = document.getElementById('box')
        box.addEventListener('mouseenter',(e)=>{
            console.log('box');
            //阻止冒泡
            //  e.stopPropagation()//停止传播
            e.stopImmediatePropagation()
            
        })
        box.addEventListener('click',()=>{
            console.log('box2');
               
        })

我们在上面的代码中给box添加了两个点击事件,当我们点击box时,会触发,如果我们使用stopImmediatePropagation()来阻止默认事件的传播,那么我们的监听器只有一个会被触发,也就是mouseenter事件,如果使用 stopPropagation()那么两个事件都会触发...

事件委托

借助冒泡机制,将原本要添加到多个子容器上的事件添加到父容器上

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head> 
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="ul">
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
        <li>e</li>
    </ul>
    <script>
        let lis = document.querySelectorAll('li')
        lis.forEach((li)=>{
            li.addEventListener('click',()=>{
                console.log(li.innerText);
            })
        })
    </script>
</body>
</html>

如果我们要在ul中的每个li上添加点击事件,按照传统方法,我们可以先获取到每个li,再遍历添加点击事件,但是这种方法属实有一点low了,我们使用在父容器上添加点击事件的方法

js 复制代码
        let ul = document.getElementById('ul')
        ul.addEventListener('click',(e)=>{
            console.log(e.target.innerText);
           
        })

ul 元素上添加了点击事件监听器。当用户点击 ul 元素内部的任意一个子元素时,事件会冒泡到 ul 元素,并触发该监听器。

在监听器中,通过 e.target 可以获取到实际触发事件的元素。通过 e.target.innerText 可以获取到该元素的文本内容。

结尾

祝掘友们新年快乐!!!!!!!!!!

相关推荐
崔庆才丨静觅7 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax