JS中的事件传播流程
1,Javascript与HTML之间的交互是通过事件实现的。
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
可以使用侦听器来预定事件,以便事件发生时执行相应代码。
2,DOM事件流存在三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。
事件流:事件发生时,事件在元素节点与根节点之间的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。事件传播顺序的两种事件流模型:事件冒泡,事件捕获。
事件捕获(event capturing):事件从最不确定的事件目标到最特定的事件目标。当鼠标点击或触发dom事件时,浏览器会从根节点开始有外向内进行事件传播,会先触发父元素,再触发子元素,由外向内层层递进。
事件冒泡(dubbed bubbling):与事件捕获刚好相反,它是由内向外进行事件触发,即从最确定的事件到最不确定的事件。
3,事件传播
通俗来讲,事件传播是从外向内,然后再从内往外。
从外到内进行事件传播,为事件捕获阶段,从内往外逐层进行传递,为事件的冒泡阶段。
4,button触发的p的click事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.main {
background-color: #e27;
padding: 2rem;
}
.mid {
background-color: #03f;
padding: 2rem;
}
p {
background-color: #300;
padding: 2rem;
}
</style>
</head> <body>
<div class="main">
<div class="mid">
<p onclick="pClickHandle(event)">
<button onclick="btnClickHandle(event)">按钮</button>
</p>
</div>
</div>
</body>
<script>
function btnClickHandle(e) {
console.log("按钮被点击了");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
}
function pClickHandle(e) {
console.log("p标签被点击了");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
} </script>
</html>
点击button ,触发点击事件,由内向外。
//target 表示触发事件的标签
//currentTarget 表示绑定事件的标签
p 标签内target是指触发的事件标签是button
currentTarget 表示绑定的p标签本身。
5,button触发的捕获阶段的事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.main {
background-color: #e27;
padding: 2rem;
}
.mid {
background-color: #03f;
padding: 2rem;
}
p {
background-color: #300;
padding: 2rem;
}
</style>
</head>
<body>
<div class="main">
<div class="mid">
<p onclick="pClickHandle(event)">
<button onclick="btnClickHandle(event)">按钮</button>
</p>
</div>
</div>
</body>
<script>
const main = document.querySelector(".main");
const mid = document.querySelector(".mid");
const btn = document.querySelector("button");
const p = document.querySelector("p");
function btnClickHandle(e) {
console.log("按钮被点击了");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
}
function pClickHandle(e) {
console.log("p标签被点击了");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
}
//assEventListener接收三个参数
//参数一,表示事件的类型
//参数二,表示事件的处理函数
//参数三,是否在捕获阶段进行触发,默认为false,此处改为true
btn.addEventListener(
"click",
function(e) {
console.log("按钮被点击了,在捕获阶段");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
},
true
);
p.addEventListener(
"click",
function(e) {
console.log("p被点击了,在捕获阶段");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
},
true
);
</script>
</html>
点击button按钮,正常情况下应该是捕获阶段先执行的,但是如下图所示后执行的捕获阶段的事件
原因是因为btn是事件源上的传播,事件源上的传播只跟添加的先后顺序有关系
//assEventListener接收三个参数
//参数一,表示事件的类型
//参数二,表示事件的处理函数
//参数三,是否在捕获阶段进行触发,默认为false,此处改为true
btn.addEventListener( //btn 为事件源
"click",
function(e) {
console.log("按钮被点击了,在捕获阶段");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
},
true
);
6,禁止事件传播
e.stopImmediatePropagation();//立即停止事件传播 , 停下来就不继续往后走了
e.stopPropagation();//停止事件传播,在我这个节点上停下来,然后从这个节点上往回走
p.addEventListener(
"click",
function(e) {
console.log("p被点击了,在捕获阶段");
console.log(e.target);
console.log(e.currentTarget);
console.groupEnd();
// e.stopImmediatePropagation(); //立即停止事件传播
e.stopPropagation(); //停止事件传播
},
true
);
以上是个人对事件传播的理解,有什么不足的地方望大家指出。