文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript中的事件冒泡与捕获怎么实现

2024-04-02 19:55

关注

这篇文章主要讲解了“JavaScript中的事件冒泡与捕获怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript中的事件冒泡与捕获怎么实现”吧!

JavaScript中的事件冒泡与捕获怎么实现

一、EventTarget 事件目标的查找方式(冒泡与捕获)

事件目标指的是绑定事件的元素,elemet.addEventListener(‘click’,function(){}) 这里的 elemet 就是事件目标。

冒泡与捕获:

addEventListener(type,listener,useCapture) 简单分析:

参数useCapture解析:

重点!!一个事件目标的触发,整个过程分为两个阶段(捕获与冒泡)。 useCapture 这个值决定事件目标的触发在哪个阶段执行。

冒泡与捕获的顺序分析:

JavaScript中的事件冒泡与捕获怎么实现

代码演示:

<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.addEventListener('click',function(){
            console.log("这是div1的点击事件");
        },false);
        div2.addEventListener('click',function(){
            console.log("这是div2的点击事件");
        },false);
        div3.addEventListener('click',function(){
            console.log("这是div3的点击事件");
        },false);
    </script>
</body>

当我们点击div3,如下从控制台结果可以看出,这里的事件都是在冒泡阶段执行。

JavaScript中的事件冒泡与捕获怎么实现

还是点击div3,我们将div1.addEventListener第三个参数改为true,如下可以看出div1最先执行,说明捕获阶段优先于冒泡阶段。

JavaScript中的事件冒泡与捕获怎么实现

这里看完一定要敲一下,我并没有列举所有的情况,其余的情况留给你们去尝试再总结(能理解上面的就够了,真正编码不会很复杂)。

如上就是我对事件目标查找的两种机制冒泡捕获理解。

二、事件代理机制(事件委托)

利用事件冒泡完成事件代理机制:

<ul>
    <li>列表1</li>
    <li>列表2</li>
</ul>

当我们要给如上列表中的li都绑定一个点击事件点击获取li中的内容,一般是利用for遍历元素绑定点击事件。

let lis = document.querySelectorAll('li');
for (let i = 0; i < lis.length; i++) {
	lis[i].addEventListener('click', function () {
 		console.log(this.innerHTML);
	});
}

假如我们有1w个 li 节点,使用如上方式就需要绑定1w个事件,这样操非常影响代码性能。所以我们可以利用冒泡机制来解决如上的问题,就是将事件绑定到父元素身上 ul 身上。看如下代码:

<body>
    <ul>
        <li>列表1</li>
        <li>列表2</li>
    </ul>
    <script>
        let ul = document.querySelector('ul');
        //我们可以通过事件对象(e)中的target属性可以访问到事件源(也就事件的触发元素)
        ul.addEventListener('click',function(e){
            console.log(e.target.innerHTML);
        },false);
    </script>
</body>

事件对象(e):无论是addEventListener绑定事件还是直接“.事件名”,事件监听的处理函数中的第一个参数为 事件对象 。事件对象包含了这个事件的详细信息,比如这个对象中包含了:事件源,事件id,事件类型,事件绑定的元素,事件触发时点击的位置等等。其中 e.target 就能访问到事件源,就是触发本次事件的源头。

既然能给父元素绑定事件监听,又能拿到触发的源头。所以我们通过“e.target”+“冒泡机制”就可以减少事件的绑定,能提升不少的性能。

依次点击列表1与列表2:

JavaScript中的事件冒泡与捕获怎么实现

总结:通过上面代码我们知道了“事件对象”+“冒泡机制”可以实现事件委托。事件委托就是当事件触发时,通过事件冒泡(或事件捕获)把要做的事委托给父元素来处理。

三、e.target与e.currentTarget的区别:

四、阻止冒泡与捕获

为什么要阻止冒泡或捕获?

点击当前元素时以冒泡的方式传递事件如果上级元素绑定了同样的事件,就会因为冒泡传递导致触发。同样捕获的过程中,也会触发与当前元素绑定的相同事件的上级。只是触发顺序不同。

事件代理一般使用的冒泡,当然阻止冒泡一般不会影响事件代理,因为顺序问题只会影响捕获事件,这也是为什么都使用冒泡实现事件代理机制。

阻止冒泡或捕获的方法

这里我不考虑兼容性问题,我相信不久将来兼容性可以得到解决。

阻止冒泡w3c推介的方法是event.stopPropagation(),顾名思义停止传播,他是事件对象(event)的方法,此方法是阻止目标元素的继续冒泡(或捕获)

event.stopPropagation()阻止冒泡:

<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.onclick = function (e) {
           alert('div1');
        }
        div2.onclick = function (e) {
           e.stopPropagation();
            alert('div2');
        }
        div3.onclick = function (e) {
           alert('div3');
        }
    </script>
</body>

上面代码默认都是冒泡事件,我们点击div3会依次弹出’div3’与’div2’,为什么没有弹出’div1’这是因为e.stopPropagation();阻止了目标元素的事件继续冒泡到上级。如果每个点击事件都加上了e.topPropagation就不会出现多弹窗的情况。

event.stopPropagation()阻止捕获:

<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.addEventListener('click',function(e){
           	console.log('div1');
        },true);
        div2.addEventListener('click',function(e){
            console.log('div2');
            e.stopPropagation();
        },true);
        div3.addEventListener('click',function(e){
            console.log('div3');
        },true);
    </script>
</body>

当我们点击div2会依次弹出’div1’与’div2’,这也是因为在div2事件中我们设置了e.stopPropagation(),阻塞了目标元素的事件继续向下捕获。

event.target == event.currentTarget:

div.addEventListener('click',function(e){
	if(event.target == event.currentTarget){
        //需要执行的代码
    }
});

此方法不过多解释用的不多,如果你理解了上面的内容,这个方法也能理解。

五、补充:为什么要使用addEventListener()

从上面代码不难看出addEventListener()有如下的优点(以下是MDN的原话):

addEventListener() 是 W3C DOM 规范中提供的注册事件监听器的方法。它的优点包括:

六、取消默认事件

event.preventDefault()

默认事件指的是<a href=""><input type="submit"> 标签这类有默认行为的标签,通过点击可以跳转或提交。我们给这类标签绑定一个点击事件,设置事件对象的preventDefault()方法就可以阻止默认事件的发生。

<body>
   <a href="https://www.baidu.com">点击跳转</a>
    <script>
        let a = document.querySelector('a');
        addEventListener('click',function(e){
            e.preventDefault();
        })
    </script>
</body>

那么我们如何才能知道一个标签是否有默认事件,打印事件对象的cancelable属性,通过事件执行就可以知道e.cancelable的结果,如果为false表示有默认事件,true则没有。

return false;

事件执行函数中设置return false取消默认事件,但此方法不常用。

感谢各位的阅读,以上就是“JavaScript中的事件冒泡与捕获怎么实现”的内容了,经过本文的学习后,相信大家对JavaScript中的事件冒泡与捕获怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯