与dom事件流相关的二三事

向dom绑定事件的事件的三种方式

  • 行内绑定
<button onclick="clickhander()">按钮</button>
  • js内绑定
btnDom.onclick = function clickHandler() {
    console.log('click');
}
  • 事件监听器绑定
btnDom.addEventListener('click', e => {
    console.log('click');
})

DOM事件流

  1. 什么是DOM事件流?

DOM结构是一个树形结构,当一个DOM元素产生一个事件,该事件会在当前节点与根节点之间的路径传播,路经的所有节点都会接收到该事件,这就是DOM事件流

  1. DOM事件流的三个阶段

    • 捕获阶段(capture):从ducoument流向目标节点
    • 目标阶段: 到达
    • 冒泡阶段:从目标阶段冒泡到document节点

关于这三个阶段的流程,文档上有个图片,描述的十分详细

与dom事件流相关的二三事

  1. 事件的执行顺序

对于target来说,事件执行,一直会在目标阶段。但对于整个事件流上的别的元素来说,执行顺序还会受到另外一个因素的影响。

我们来看一个例子,首先dom结构如下

<div id="fa">
    <div id="ch"></div>
</div>

为其绑定事件

fa.addEventListener('click', e => {
  console.log('click fa')
})

ch.addEventListener('click', e => {
  console.log('click ch')
})

此时点击ch,打印出的结果是

"click ch"
"click fa"

先执行了ch的事件,后执行了fa的事件,因此我们可以得知,fa的事件,是在冒泡阶段被执行的。

addEventListener方法,可以传入第三个参数,useCapture,boolean,来决定这个执行阶段。默认为false,也就是在冒泡阶段,如果设置为true,则会在捕获阶段

fa.addEventListener('click', e => {
  console.log('click fa')
}, true)

ch.addEventListener('click', e => {
  console.log('click ch')
}, true)

执行结果为

"click fa"
"click ch"
  1. stopPropagation

在事件流的任何一个事件,都可以调用event的stopPropagation方法,来停止事件流。以上面的场景为例,在捕获阶段执行fa的事件,如果执行stopPropagation,则事件流终止,不会到达目标阶段,ch的世界则不会被执行

fa.addEventListener('click', e => {
  console.log('click fa')
  e.stopPropagation();
}, true)

ch.addEventListener('click', e => {
  console.log('click ch')
}, true)

执行结果为

"click fa"

线上demo

参考

相关推荐