Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

冒泡与捕获 #19

Open
Twlig opened this issue Mar 6, 2022 · 0 comments
Open

冒泡与捕获 #19

Twlig opened this issue Mar 6, 2022 · 0 comments

Comments

@Twlig
Copy link
Owner

Twlig commented Mar 6, 2022

当点击一个按钮时,实际上不光点击了这个按钮,还点击了它的容器以及整个页面。那么如何获取事件的发生先后顺序,就反映了事件流。

事件流描述了页面接收事件的顺序。有事件冒泡事件捕获两种。

事件冒泡

事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。

如:

<!DOCTYPE html> 
<html> 
<head> 
 <title>Event Bubbling Example</title> 
</head> 
<body> 
 <div id="myDiv">Click Me</div> 
</body> 
</html>

在点击页面中的<div>元素后,click 事件会以如下顺序发生:

1. <div>
2. <body>
3. <html>
4. document

<div>元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿 DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。

事件捕获

最不具体的节点最先收到事件,而最具体的节点最后收到事件。事件捕获实际上是为了在事件到达最终目标
前拦截事件

如果前面的例子使用事件捕获,则点击<div>元素会以下列顺序触发 click 事件:

1. document
2. <html>
3. <body>
4. <div>

在事件捕获中,click 事件首先由 document 元素捕获,然后沿 DOM 树依次向下传播,直至到达实际的目标元素<div>

通常建议使用事件冒泡,特殊情况下可以使用事件捕获。

事件流

DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。

  • 事件捕获最先发生,为提前拦截事件提供了可能。
  • 然后,实际的目标元素接收到事件。
  • 最后一个阶段是冒泡,最迟要在这个阶段响应事件。

image

注意:

由于存在事件冒泡,注册点击事件的顺序无关,只和事件冒泡的顺序有关,从内到外

document.body.onclick = function(event) { 
 console.log("Body clicked"); 
};
btn.onclick = function(event) { 
 console.log("Clicked"); 
}; 
//Clicked
//Body clicked     
//事件触发和注册点击事件的顺序无关,只和事件冒泡的顺序有关,从内到外,先btn触发,再是body

插播一个阻止冒泡的方法stopPropagation()

let btn = document.getElementById("myBtn"); 
btn.onclick = function(event) { 
 console.log("Clicked"); 
 event.stopPropagation();     //阻止事件冒泡,body点击事件无法触发
}; 
document.body.onclick = function(event) { 
 console.log("Body clicked"); 
};
//Clicked

补充:

大多数事件都支持冒泡,但是还有少数事件不支持:

  1. UI事件:load、unload、 scroll、resize
  2. 焦点事件:blur、focus
  3. 鼠标事件:mouseleave、mouseenter

这些事件仅发生于自身上,而它的任何父节点上的事件都不会产生,所有不会冒泡。

@Twlig Twlig changed the title JavaScript基础篇之冒泡与捕获 冒泡与捕获 Mar 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant