浏览器事件的捕获和冒泡,这次彻底弄懂一下?

999 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

事件捕获和冒泡

    // 注册冒泡事件
    document.querySelector('.div_box').addEventListener('click', function(e) {
        console.log('%c [target]', 'color: pink;', e.target);
        console.log('%c [currentTarget]', 'color: pink;', e.currentTarget);
        console.log('[bubble] div_box is clicked.');
    }, false);

    // 注册捕获事件
    document.querySelector('.div_box').addEventListener('click', function(e) {
        console.log('%c [target]', 'color: pink;', e.target);
        console.log('%c [currentTarget]', 'color: pink;', e.currentTarget);
        console.log('[capture] div_box is clicked.');
    }, true);

bubble

知识点:

1、(常规)事件的流转顺序按照 父捕获 -> 子捕获 -> 子冒泡 -> 父冒泡顺序执行

2、addEventListener 的第三个参数类型为 Boolean 类型,用于控制事件的执行是在捕获阶段还是冒泡阶段;默认值false,冒泡阶段;

3、回调函数中的 e.target 为事件触发的元素,e.currentTarget 为事件的绑定元素

问题1: 如何阻止事件的冒泡?

1、官方方法: e.stopPropagation();

2、伪阻止: 通过判断 e.targete.currentTarget 是否===

问题2: 一个元素上同时绑定了冒泡事件和捕获事件,先触发哪个?

这个问题要分浏览器版本(讨论Chrome)

在Chrome 89.0.4363.0(包含) 版本之,统一了事件流的标准,同一个dom元素,同时绑定冒泡捕获事件,按照捕获冒泡的顺序执行

在Chrome 89.0.4363.0(包含) 版本之,统一了事件流的标准,同一个dom元素,同时绑定冒泡捕获事件,按照代码的书写顺序执行;意味着如果先写冒泡事件代码,在写捕获事件代码,则先执行冒泡事件,再执行捕获事件

参考资料

    /**
     * 老版本chrome,先输出 `bubble event is show` 再输出 `capture event is show`
     * 
     * 新版本chrome 按照先捕获、再冒泡的顺序执行
     * 
     */
    // 示例代码
    document.querySelector('.div_box').addEventListener('click', function(e) {
        console.log('bubble event is show');
    }, false);

    document.querySelector('.div_box').addEventListener('click', function(e) {
        console.log('capture event is show');
    }, true);