乐趣区

关于前端:面试官哪些浏览器事件不会冒泡

你晓得哪些浏览器事件不会冒泡吗?

答复这个问题之前,咱们首先要具备 DOM 事件流捕捉与冒泡 的常识,这里只讲 JS 中如何设置这两种事件监听,例如对 body 注册点击事件:

document.body.addEventListener('click', e => {console.log('触发捕捉阶段');
}, true)

document.body.addEventListener('click', e => {console.log('触发冒泡阶段');
}, false)

具体区别在第三个参数,w3c 规定了 true 示意捕捉阶段触发,false示意冒泡阶段触发,默认false

在 JS 中通常利用 冒泡 来进行 事件委托,但并不是所有事件都会冒泡。上面咱们看看哪些事件是不能冒泡的,又有哪些相干利用场景。

scroll、focus、blur、resize

假如有如下一段 html 构造

<ul id="container">
    <ul id="outer">
        <div id="inner"></div>
    </ul>
</ul>

咱们只需设置overflow: scroll;,当内层长度超出外层时元素就会呈现滚动条,此时应有两个滚动事件,咱们别离为 containerouter 增加 scroll 监听:

document.getElementById('container').addEventListener('scroll',
    function (e) {console.log('container scroll')
    },
);

document.getElementById('outer').addEventListener('scroll',
    function (e) {console.log('outer scroll')
    },
);

此时滚动内层,咱们看到并不会触发外层的事件监听:

而如果设置成 捕捉 监听呢?

document.getElementById('container').addEventListener('scroll',
    function (e) {console.log('container scroll')
    },
    true
);

document.getElementById('outer').addEventListener('scroll',
    function (e) {console.log('outer scroll')
    },
    true
);

通过这个例子咱们能够得出结论,scroll无奈触发冒泡,而捕捉事件能够失常触发,所以 scroll 必须在捕捉阶段能力实现事件委托。

留神:有个相似滚动事件的叫 滚轮 事件 wheel 是能够触发冒泡的(MDN – wheel_event),咱们甚至能够通过额定注册 wheel 监听事件并阻止其冒泡从而让 scroll 事件生效,不过只有滚动条还在 scroll 还是能够不通过滚轮来管制滚动的,所以还记得后面咱们怎么让元素滚动起来的吗?就是设置了 overflow: scroll;,所以管制滚动应该应用 CSS 而不是 JS 事件。

focusblurresize 这几个事件和 scroll 情理是一样的,都不会触发冒泡,所以事件也都不能通过阻止冒泡勾销,它们了解起来比拟直观,就不多做论述了。

mouseenter、mouseleave

mouseover & mouseenter 均为鼠标挪动到元素上的事件,两者区别在于后者不会冒泡。

<ul id="outer">
    <li id="inner"></li>
</ul>

假如给 ul 设置了 mouseover 事件,在鼠标通过 ul 时因为 ul 中还有 li 元素,鼠标每通过一个 li 元素就会冒泡到 ul 上的 mouseover,造成屡次触发:

document.getElementById('outer').addEventListener('mouseover',
    function() {console.log('鼠标进入了外层');}
);
document.getElementById('inner').addEventListener('mouseover',
    function() {console.log('鼠标进入了内层');}
);

这时就须要在内层额定阻止冒泡(e.stopPropagation())能力解决屡次触发的问题,不过鼠标从 li 移出到 ul 上还是触发了 ul 的监听事件,其实这并不合乎常理,因为此时鼠标还是在 ul 内的。相比之下间接应用 mouseenter 就不会呈现以上这些问题了。

同样的,mouseout会冒泡,而 mouseleave 则不会冒泡。

Media

由视频、图像、音频等媒体触发的相干事件,都不会触发冒泡,和 scroll 事件同理,如果须要进行事件委托都必须在 捕捉阶段 去解决。

结尾

古代 JS 框架均对事件体系做了相干解决,很多时候开发者可能会疏忽事件委托的一些机制,理解其中细节与不同事件之间的差别,能够无效防止理论开发中呈现的坑。

以上就是文章的全部内容,心愿对你有所帮忙!如果感觉文章写的不错,能够点赞珍藏,也欢送关注,我会继续更新更多前端有用的常识与实用技巧,我是茶无味 de 一天,心愿与你独特成长~

退出移动版