JavaScript事件流(冒泡、捕获)
引言
我们给下面的四个圆圈都添加鼠标点击事件,要求鼠标点击时圆圈会变为粉色,效果如下:

但当我们直接点击最中间的圆圈时却发现所有的圆圈都会变色:

很多初学者可能会认为这是一种包含关系,但在 JavaScript 中这叫事件流。我们来看看点击事件的代码:
上面这个点击变色的案例,通过循环的方式给每个 span 元素添加鼠标点击事件,一共添加了4个。接下来利用事件委托的方式来小小的升级一下!
let div = document.querySelector('div');
div.addEventListener('click', function(event) {event.target.style.backgroundColor = "#ffb900";
});
这里给回调函数传入了一个事件对象 event,event.target 表示的是事件目标,即我们点击的那个元素。这里,我们点击的是 span 元素,所以 event.target 指向的就是 span 元素。由于 span 元素并没有被添加事件监听器,所以不会有任何事件被触发,根据冒泡机制,向上触发事件的是 div 元素。div 元素的事件被触发后,如何判断点击的是哪个 span 呢?event.target 已经告诉它了!
如果还是不明白 event.target 在这里的作用,建议去了解下 JavaScript事件对象
事件冒泡的缺点:当父元素和子元素都添加了事件监听器,根据冒泡机制,点击子元素时,父元素的事件也会被触发。而我们只想触发子元素的事件,不想触发父元素的事件时,该怎么办?看下面这个例子:

我想实现点击粉色区域变为橙色,点击绿色区域让橙色变为粉色。但上述代码似乎无法达到效果,这是因为点击粉色区域后,粉色区域会变为橙色,根据冒泡机制,向上触发绿色区域的点击事件,从而导致橙色又被变回粉色,所以看上似乎没有产生任何变化。这里的冒泡机制就成了累赘,我们需要阻止事件冒泡!
span.addEventListener('click', function(event) {this.style.backgroundColor = "#ffb900";event.stopPropagation(); // 阻止事件冒泡
});
修改代码后,看看效果:

事件捕获
定义:事件从最不具体的元素开始执行(文档),向下传播至最具体的元素(被点击的元素)。
现在的浏览器,从 window 对象开始向下传递。
事件捕获和事件冒泡是一个完全相反的行为,但有一点需要注意!旧版本的浏览器(IE9之前)并不支持事件捕获。
总结
-
实际开发中,事件冒泡用的会更多,事件捕获一般用在特殊情况下。
-
利用事件委托可以有效的提高程序性能。
-
DOM2 Events 规范将事件流分为三个阶段:事件捕获、到达目标、事件冒泡。并规定事件捕获阶段不触发目标事件,而事件冒泡阶段会在目标事件被触发后执行。但现在的浏览器并没有按照这个规定来实现事件流,在事件捕获阶段的终点,任然还是会触发目标事件,所以对于现在的浏览器而言,不管是捕获还是冒泡,目标事件都会被触发。
本文参考自《JavaScript高级程序设计》第4版
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
