分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

js的事件流你真的弄明白了吗?

发布时间:2023-09-06 02:20责任编辑:傅花花关键词:js

当浏览器发展到第四代时候,浏览器开发团队遇到了一个有意思的问题;页面的哪一部分会拥有某个特地的事件?要明白这个问题问的是什么,可以想象画在纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的不是一个圆,而是纸上所有的圆。两家公司的开发团队在这件事情上的看法是一致的,如果你单击了某个按钮,他们都认为单击事件不仅发生在按钮上,更是发生在了整个容器元素,甚至是整个页面。

那么对于页面接收事件的顺序两者出现了不同的定义:捕获流 ( chrome )冒泡流( IE )。在事件监听addEventListener的第三个参数中,捕获流是 true,冒泡流是 false。主流浏览器默认的都是冒泡流机制,也就是第三个参数默认false。

事件捕获:window -> document -> html -> body -> button  (原先的‘DOM2级事件’本来是规定事件应该从document对象出发的,但是后面几乎所有的浏览器还是拓展到了window对象层面)

事件冒泡:button -> body -> html -> document -> window  

事实上‘DOM2级事件’规定的事件流包括了三个阶段: 事件捕获阶段,处于目标阶段,事件冒泡阶段。(原先是规定捕获阶段不涉及事件目标的,但是后面高版本都会在捕获阶段触发事件对象上的事件)

重点:处于目标阶段,即button的事件在捕获阶段和冒泡阶段都会被触发。

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style>.box{ ???position: relative; ???background-color: coral; ???border: 1px solid; ???padding: 50px;}.child { ???position: relative; ???background-color: pink; ???width: 100px; ???height: 100px;}</style></head><body><div id="A" class="box"> ???<div id="B"> ???????<div id="C" class="child">点击该方块, 我是冒泡</div> ???</div></div><br><script>document.getElementById("A").addEventListener("click", function(e){ ???console.log("1 捕获");}, true);document.getElementById("B").addEventListener("click", function(e){ ???console.log("2 捕获"); ???// e.stopPropagation()}, true);document.getElementById("C").addEventListener("click", function(e){ ???console.log("捕获阶段触发目标"); ???// e.stopPropagation()}, true);document.getElementById("C").addEventListener("click", function(){ ???console.log("冒泡触发目标");}, false);document.getElementById("B").addEventListener("click", function(){ ???console.log("1 冒泡");}, false);document.getElementById("A").addEventListener("click", function(){ ???console.log("2 冒泡");}, false);</script></body></html>

  

 

执行结果如下:

值得注意的是,捕获阶段或者冒泡阶段对应的在 C 上的事件其实并不是 先捕获阶段触发目标 然后是冒泡阶段触发目标,在C上的事件其实是都是触发的,触发顺序取决于你写的顺序。不信,换下顺序如下

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style>.box{ ???position: relative; ???background-color: coral; ???border: 1px solid; ???padding: 50px;}.child { ???position: relative; ???background-color: pink; ???width: 100px; ???height: 100px;}</style></head><body><div id="A" class="box"> ???<div id="B"> ???????<div id="C" class="child">点击该方块, 我是冒泡</div> ???</div></div><br><script>document.getElementById("A").addEventListener("click", function(e){ ???console.log("1 捕获");}, true);document.getElementById("B").addEventListener("click", function(e){ ???console.log("2 捕获"); ???// e.stopPropagation()}, true);document.getElementById("C").addEventListener("click", function(){ ???console.log("冒泡触发目标");}, false);document.getElementById("C").addEventListener("click", function(e){ ???console.log("捕获阶段触发目标"); ???// e.stopPropagation()}, true);document.getElementById("B").addEventListener("click", function(){ ???console.log("1 冒泡");}, false);document.getElementById("A").addEventListener("click", function(){ ???console.log("2 冒泡");}, false);</script></body></html>

 执行结果如下:

接下来继续说一下阻止冒泡,假设我在  console.log("1 捕获") 或者 console.log("2 捕获") 后面加上  e.stopPropagation(),后面的事件还能触发吗?单单是只把冒泡流扼杀了吗?

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style>.box{ ???position: relative; ???background-color: coral; ???border: 1px solid; ???padding: 50px;}.child { ???position: relative; ???background-color: pink; ???width: 100px; ???height: 100px;}</style></head><body><div id="A" class="box"> ???<div id="B"> ???????<div id="C" class="child">点击该方块, 我是冒泡</div> ???</div></div><br><script>document.getElementById("A").addEventListener("click", function(e){ ???console.log("1 捕获"); ???e.stopPropagation()}, true);document.getElementById("B").addEventListener("click", function(e){ ???console.log("2 捕获"); ???}, true);document.getElementById("C").addEventListener("click", function(){ ???console.log("冒泡触发目标");}, false);document.getElementById("C").addEventListener("click", function(e){ ???console.log("捕获阶段触发目标"); ???// e.stopPropagation()}, true);document.getElementById("B").addEventListener("click", function(){ ???console.log("1 冒泡");}, false);document.getElementById("A").addEventListener("click", function(){ ???console.log("2 冒泡");}, false);</script></body></html>

  

事实上,它是把后面的事件流都打断了。而如果 e.stopPropagation() 是写在  console.log("捕获阶段触发目标") 或者  console.log("冒泡触发目标")后面,目标阶段都点击事件都会执行,执行按你写的顺序来。

Propagation英文意思是‘传播’ stopPropagation 就是阻止事件传播,阻止事件流的继续往下发生。

所以stopPropagation()方法事实上是打断了事件流继续执行,而我们一般时候是直接写在目标事件的点击函数里,就起到了阻止冒泡的作用!

  

js的事件流你真的弄明白了吗?

原文地址:https://www.cnblogs.com/hjj2ldq/p/9892409.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved