说说事件冒泡和事件捕获
「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。
在我们日常前端面试中经常会被问到什么是事件冒泡和事件捕获,在什么时候被触发,有什么关联等。那么究竟什么是事件冒泡和事件捕获呢,又有什么区别呢,我们一起看看吧!
事件冒泡
简单来说,事件冒泡就是在一个对象上绑定事件,如果定义了事件的处理程序,就会调用处理程序。相反没有定义的话,这个事件会向对象的父级传播,直到事件被执行,最后到达最外层,document对象上。
1.为什么会出现事件冒泡?
- 事件冒泡允许多个操作被集中处理(把事件处理器放在父级元素),这样统一处理,方便高效 举个栗子:
<div onclick="eventHandle(event)" id="outSide">
<div id="inSide"></div>
</div>
- 不同的对象同时捕获同一事件 举个栗子:
<div onclick="outSideWork()" id="outSide">
<div onclick="inSideWork()" id="inSide"></div>
</div>
2.阻止事件冒泡
举个栗子:
// 阻止事件冒泡函数
function stopBubble(e){
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
事件捕获
事件捕获和事件冒泡是一个完全相反的过程,即事件从外一直向里传递。
- 浏览器先检查外层的祖先
html
,如果在捕获阶段注册了一个onclick
事件,就运行。 - 向里层元素传递,执行相同的操作,直到实际点击的元素上。
现在的浏览器默认情况下,所有的事件处理程序都在冒泡阶段注册,所以点击子元素时,会执行子元素上的事件,向上冒泡,触发父元素上的事件。
addEventListener
函数的第三个参数是个布尔值。
- 当布尔值是
false
时(默认值),表示向上冒泡触发事件; - 当布尔值是
true
时,表示向下捕获触发事件;
不能冒泡的事件
blur
元素失去焦点时触发,focusout
事件也是失去焦点时触发,但可以冒泡;focus
元素获取焦点时触发;mouseenter
鼠标移动到元素上时会触发该事件,与之对应的是mouseover
事件(会冒泡);mouseleave
鼠标离开元素时触发,与之对应的是 mouseout(会冒泡);
事件对象中的方法
stopPropagation()
阻止事件冒泡,设置之后,点击该元素时父元素绑定的事件就不会再触发;preventDefault()
阻止默认事件发生;stopImmediatePropagation()
用来阻止监听同一事件的其他事件监听器被调用以及阻止事件冒泡
target 和 currentTarget的区别
target
属性指向的是事件目标,而 currentTarget
属性指向的是正在处理当前事件的对象,它总是指向事件绑定的元素。而 target
指向的可能不是定义时的事件目标。
举个栗子:
div.addEventListener('click', (e) => {
console.log(e.target, e.currentTarget);
},false);
e.target
可能指向 div
元素,也可能指向它的子元素。而 e.currentTarget
总是指向 div
元素。
举个栗子:
const ipt = document.querySelector('input');
ipt.addEventListener('click', () => {
console.log('click');
},false);
ipt.addEventListener('focus', () => {
console.log('focus');
}, false);
ipt.addEventListener('mousedown', () => {
console.log('mousedown');
}, false);
ipt.addEventListener('mouseenter', () => {
console.log('mouseenter');
}, false);
打印结果:
mouseenter // 鼠标移动到元素上时触发
mousedown // 鼠标按下时触发
focus // 输入框有焦点时触发
click // 点击事件最后触发
以上就是关于事件冒泡和事件捕获的一些概念了,希望怼你有帮助!
转载自:https://juejin.cn/post/7066440009397567501