云计算百科
云计算领域专业知识百科平台

javascript 事件流的捕获和冒泡

问题出现的场景是,父元素和子元素使用同样的事件(点击)然后点击触发会两个都触发,如果只想用触发父元素呢   或者如果只想触发子元素呢?

事件详解

事件绑定方式

直接在元素上绑定 <div οnclick="fun()">

通过元素赋值的方法绑定

div.onclick = function(){}

通过监听器的方式绑定

const div = document.querySelector("div")
div.addEventListener("click",function(){},true/false);

addEventListener("事件名称","执行函数“,"事件机制”)

事件机制默认false即  忽略什么都不填

事件流

这个问题需要了解一下事件流

事件流就是事件在DOM树中传播的过程中,一个传播执行的顺序

过程:事件捕获阶段,目标阶段,事件冒泡阶段

事件流分为捕获事件流和冒泡事件流

捕获事件流:事件从目标元素向根节点传播的过程

冒泡事件流:事件从根节点向目标元素传播的过程

事件机制

冒泡:元素嵌套时,外层元素和内层元素存在相同的事件,那么事件会从内向外依次触发

  • true:捕获机制
  • false:冒泡机制

捕获:元素嵌套时,外层元素和内层元素存在相同事件,由外到内依次触发

阻止事件流

  • 阻止冒泡

e.stopPropagation():阻止事件传播 (同样也是阻止冒泡)

  • 阻止默认行为

e.preventDefault()

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.outer {
width: 500px;
height: 500px;
border: 1px solid;
background-color: red;
}

.inner {
width: 200px;
height: 300px;
border: 1px solid white;
background-color: aqua;
}
</style>
</head>

<body>
<div class="outer">div2
<div class="inner">div1</div>
</div>

<script>
const outer = document.getElementsByClassName("outer")[0];
const inner = document.getElementsByClassName("inner")[0];

// 添加事件监听器
outer.addEventListener('click', function (e) {
console.log("outer 的捕获 监听器被触发");
// e.stopPropagation(); //
}, true);
outer.addEventListener('click', function (e) {
console.log("outer 的冒泡监听器被触发");
// e.stopPropagation();
}, false);
inner.addEventListener('click', function (e) {
console.log("inner 的捕获监听器被触发");
// e.stopPropagation();
}, true);

inner.addEventListener('click', function (e) {
console.log("inner 的冒泡捕获监听器被触发");
// e.stopPropagation();
}, false);

</script>
</body>

</html>

可以用这个自测一下,这是最初的样子

当在outer捕获的监听器里加上 e.stopPropagation();

补充一下 这个e 是事件对象event  是监听器在执行回调函数中的第一个参数,事件对象

  • 事件在捕获阶段被 outer 捕获后,stopPropagation() 阻止了事件继续向下传播(不会到达 inner)。

  • 因此,inner 的捕获和冒泡监听器都不会触发,outer 的冒泡监听器也不会触发。

第二个是outer冒泡监听器添加 e.stopPropagation();

  • 事件会正常完成捕获阶段和目标阶段(inner 的监听器会触发)。

  • 在冒泡阶段,事件到达 outer 的冒泡监听器时被阻止,但此时事件已经完成了目标阶段的传播。

  • stopPropagation() 在冒泡阶段的作用是阻止事件继续向上传播(例如,阻止父元素的冒泡监听器),但对捕获阶段无影响。

然后给inner的捕获监听器加上阻止传播方法,

  • 事件在捕获阶段会依次触发 outer 和 inner 的捕获监听器。

  • 在 inner 的捕获监听器中调用 stopPropagation() 会阻止事件继续向下传播(虽然已经到达目标,但不会触发目标阶段的冒泡监听器)。

  • 因此,inner 的冒泡监听器和 outer 的冒泡监听器都不会触发。

最后给inner的冒泡添加阻止

  • 事件会正常完成捕获阶段和目标阶段。

  • 在 inner 的冒泡监听器中调用 stopPropagation() 会阻止事件继续向上冒泡(outer 的冒泡监听器不会触发)。

总结

stopPropagation()的作用

首先确实都是阻止事件进一步传播

在捕获阶段调用时,会阻止事件向下传播到目标

在冒泡阶段调用时,会阻止事件向上传播到父元素

事件流是 捕获阶段-》目标阶段-》冒泡阶段 

且捕获阶段是从外到内

目标阶段:触发目标元素的监听器(按注册顺序,先捕获后冒泡)

冒泡阶段是从内到外

回归问题 

  • 冒泡阶段的 stopPropagation() 可阻止父元素触发。

  • 捕获阶段的 stopPropagation() 可阻止子元素触发

  • 差不多测试完就明白 事件冒泡的原理了  然后再阻止……

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » javascript 事件流的捕获和冒泡
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!