DOM事件流
网页是由若干个或嵌套、或并排的盒子组成的。
当一个用户点击事件发生在一个元素上时,该元素就是事件的目标,然而它的容器盒子、以及容器的容器等都将接收到这个事件。
这些盒子接收事件的顺序将影响事件处理程序的执行顺序,到底是从里到外还是从外到里呢?事件流就是用来描述这个的。
DOM结构
一个网页被渲染到浏览器后,其DOM结构是这样的:
事件冒泡和事件捕获
事件冒泡是从里到外,当上图中h1被点击时,接收事件的顺序是:h1 --- section --- body --- html --- document。而事件捕获完全与事件冒泡相反,其用意是在事件到达目标之前就捕获它。
DOM2级事件流
现在DOM2级事件明确规定事件流分为三个阶段:捕获阶段、目标阶段、冒泡阶段。也就是说,在h1上发生的点击事件会先从document传到h1,再一路传回document。
事件处理程序
为元素绑定事件处理程序时需要交代清楚三个东西:监听什么事件?执行哪个回调函数?在事件流的哪个阶段调用回调函数?
绑定事件的方法有两种:
-
btn.onclick = function(){}
此时回调函数会在冒泡阶段调用。
-
btn.addEventListener('click', btnClick, false)
,false
表示在冒泡阶段调用,true
,表示在捕获阶段调用。 -
jQuery的事件处理都是在冒泡阶段。
事件对象 · 阻止默认行为、阻止事件传播
当一个事件被触发时,就会有一个事件对象被传入事件处理程序。
在事件处理程序内可以调用事件对象的方法来阻止默认行为(preventDefault)或者阻止事件传播(stopPropagation):
let link = document.getElementById("link"); //获取一个<a元素
link.onclick = function(event){
alert('链接被点击了');
event.preventDefault();
//如果该链接的父元素上也绑定了一个点击事件,则需要避免触发它
event.stopPropagation();
}
无论是在捕获阶段还是在冒泡阶段阻止了传播,其他元素上的相同事件就不会被触发了。