Q:JavaScript 中事件流是什么?如何传递。
A:我们先对问题进行拆分来看什么是事件,什么是事件流,最后就是事件流如何传递的。
- 事件是用户对页面交互进行实现的方式。
- 事件流描述的就是从页面中接收事件的顺序。而早期的IE和Netscape提出了完全相反的事件流概念,IE事件流是事件冒泡,而Netscape的事件流就是事件捕获。
- 当我们通过
addEventListener对DOM元素添加事件,不传递参数时,为冒泡事件: 该图展示了下方代码结构的事件流方向(事件冒泡)HTMLJavaScript所以以上方法打印的顺序为:
Q:在一个 div 的内部有一个 span 元素,给两个元素都添加上点击事件,怎么让 div 的事件先于 span 出发,使用原生 JavaScript 实现。
A:这个问题其实很简单,就是看对基础 API 够不够熟悉,我们指定原生 JavaScript 添加事件可以使用 addEventListener 这个 API ,我们来看看 MDN 上面对这个 API 的语法解释。
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture);
target.addEventListener(type, listener, useCapture, wantsUntrusted ); // Gecko/Mozilla only
我们可以看到除了前两个参数还有第三个参数:
useCapture:在DOM树中,注册了事件的元素, 是否要先于它下面的EventTarget,调用该事件。 当useCapture(设为true) 时,沿着DOM树向上冒泡的事件,不会触发事件。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。
所以我们将上方的 JavaScript 修改为如下,可以可以让注册事件流变为捕获事件:
该注册事件打印的顺序为:
所以其实实现这个问题很简单,只需要将
Parent 事件的 useCapture 设置为 true 就可以解决了。
不说了,啃书去了,该补一补基础了。