在项目上遇到一些与事件流相关的问题,研究如下,网上的解释都不清楚,而且都是一个抄一个,所以还是建议去看下这本书《JavaScript高级程序设计第三版》dom的那一章。
https://github.com/shihyu/JavaScript/blob/master/books/JavaScript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%EF%BC%88%E7%AC%AC3%E7%89%88%EF%BC%89%E3%80%91%E4%B8%AD%E6%96%87%20%E9%AB%98%E6%B8%85%20%E5%AE%8C%E6%95%B4%20%E8%AF%A6%E7%BB%86%E4%B9%A6%E7%AD%BE%E7%89%88.pdf
总结下:
首先当我们在页面上触发一个事件的时候,DOM遵循这样的事件流(捕获->目标->冒泡)。
举个例子:
<html lang="zh-cn">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>js事件机制</title>
<style>
#parent{
width: 200px;
height:200px;
text-align: center;
line-height: 3;
background: green;
}
#child{
width: 100px;
height: 100px;
margin: 0 auto;
background: orange;
}
</style>
</head>
<body>
<div id="parent">
父元素
<p id="child">
子元素
</p>
</div>
<script type="text/javascript">
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
// console.log(e);
console.log(elementName);
console.log("click-body");
},false);
parent.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
// console.log(e);
console.log(elementName);
console.log("click-parent");
},true);
child.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
console.log(elementName);
console.log("click-child");
},false);
</script>
</body>
</html>
这个时候去点击子元素,如下:

- 解释:首先事件从最外层捕获,document发现click是在冒泡阶段获取,所以先不执行。到parent发现是在捕获阶段,所以在这时就可以先执行了。然后到child位目标元素,开始冒泡。所以document在冒泡阶段执行。
换个例子:
document.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
// console.log(e);
console.log(elementName);
console.log("click-body");
},true);
parent.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
// console.log(e);
console.log(elementName);
console.log("click-parent");
},false);
child.addEventListener("click",function(e){
const element = event.srcElement;
const elementName = element.localName;
console.log(elementName);
console.log("click-child");
},true);

这个时候是document先执行,因为正好是true,表示是在捕获阶段执行,但是到parent的时候,发现是在冒泡阶段执行,所以不执行,要等到冒泡阶段才执行。然后开始执行child事件。
function(e)中的e都表示的目标dom
网友评论