Skip to content
当前页面

事件冒泡、事件捕获、事件委托

一、事件冒泡和捕获

运行条件:当一个事件发生在具有父元素的的元素上时,现代浏览器根据事件添加时的设置来执行(冒泡或者捕获)

通过 addEventListener() 的第三个属性来设置事件是通过捕获阶段注册的(true),还是冒泡阶段注册的(false)。默认情况下是 false。

冒泡图解

1、事件冒泡

从实际操作的元素(事件)向上级父元素一级一级执行下去,直到达到document

注意:

在JavaScript中,并非所有的事件都可以冒泡,像:blur、unload、load等事件就不能冒泡

有些时候父元素和子元素都定义了click事件,但是不希望点击子元素的时候执行父元素的click事件(例如dialog弹窗的遮罩层如果是父元素,而dialog弹窗内容层是子元素,同时可以通过点击遮罩层来关闭弹窗,但是点击内容层不关闭弹窗),可以通过stopPropagation()在子元素上阻止冒泡。vue使用.stop

2、事件捕获(不常用)

当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点 =>事件源(由外到内)进行事件传播。

二、事件委托

又称事件代理:将原本作用在子元素的事件写在父元素,而子元素通过事件冒泡的原理,会触发绑定在父元素上的事件,这就是事件委托。

作用:

  • 可以节省内存,不需要给所有子元素绑定事件
  • 新增的子元素依旧会拥有事件

提示:

适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。(所有用到按钮的事件,多数的鼠标事件和键盘事件) 值得注意的是,mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。 不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说focus,blur之类的,本身就没用冒泡的特性,自然就不能用事件委托了。