JavaScript中捕获与冒泡详解及实例


Posted in Javascript onFebruary 03, 2017

JavaScript中捕获/阻止捕获、冒泡/阻止冒泡

事件流描述的是从页面中接收事件的顺序。提出事件流概念的正是IE和Netscape,但是前者提出的是我们常用的事件冒泡流,而后者提出的是事件捕获流。

第一部分:事件冒泡

即事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。

下面举一个简单的例子:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>bubble</title>
 <style>
  button{
   background: red;
   color:white;
  }
  #third{
   width: 50px;
   height: 50px;
   border:thin solid red;
  }
  #second{
   width: 100px;
   height: 100px;
   border:thin solid red;
  }
  #first{
   width:200px;
   height: 200px;
   border:thin solid red;
  }
 </style>
</head>
<body>
 <div id="first">
  <div id="second" >
   <div id="third" >
    <button id="button">事件冒泡</button>
   </div>
  </div>
 </div>
 <script>

  document.getElementById("button").addEventListener("click",function(){
   alert("button");
  },false);

  document.getElementById("third").addEventListener("click",function(){
   alert("third");
  },false);

  document.getElementById("second").addEventListener("click",function(){
   alert("second");
  },false);  

  document.getElementById("first").addEventListener("click",function(){
   alert("first");
  },false);

 </script>
</body>
</html>

这时,我们只点击button元素,效果如下:

JavaScript中捕获与冒泡详解及实例

可以看到,虽然我们只点击了button元素,但是,button外的third、second、first上的事件由内向外以此被触发,触发的顺序是由DOM树的下层到DOM树的最上面,故称为冒泡

说明:尽管这里我使用了DOM2级事件处理程序,并设置每个事件为冒泡阶段发生,但是即使使用DOM0级,得到的结果也是这样的,冒泡是默认的

但是如果我们不希望事件冒泡呢?那么如何阻止事件冒泡

实际上,事件的对象有一个stopPropagation()方法可以阻止事件冒泡,我们只需要把上个例子中button的事件处理程序修改如下:

document.getElementById("button").addEventListener("click",function(event){
   alert("button");
   event.stopPropagation(); 
  },false);

这样,点击button后,只会弹出一个弹窗,显示button。

注意:现代所有的浏览器都支持事件冒泡,只是在实现上有一些差别。

第二部分:事件捕获

事件捕获和事件冒泡是刚好相反的,事件捕获是指不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件。举例如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>bubble</title>
 <style>
  button{
   background: red;
   color:white;
  }
  #third{
   width: 50px;
   height: 50px;
   border:thin solid red;
  }
  #second{
   width: 100px;
   height: 100px;
   border:thin solid red;
  }
  #first{
   width:200px;
   height: 200px;
   border:thin solid red;
  }
 </style>
</head>
<body>
 <div id="first">
  <div id="second" >
   <div id="third" >
    <button id="button">事件冒泡</button>
   </div>
  </div>
 </div>
 <script>

  document.getElementById("button").addEventListener("click",function(){
   alert("button");
  },true);

  document.getElementById("third").addEventListener("click",function(){
   alert("third");
  },true);

  document.getElementById("second").addEventListener("click",function(){
   alert("second");
  },true);  

  document.getElementById("first").addEventListener("click",function(){
   alert("first");
  },true);

 </script>
</body>
</html>

大家可以看到这个例子我只是把addEventListener()方法的第三个参数由前面例子的false修改为了true,也就是使用捕获方式获得button,那么结果如下:

JavaScript中捕获与冒泡详解及实例

我们可以看到最外层的事件先被触发,最后才是我们点击的button事件被触发,这便是事件捕获。

 那么我们如何才能阻止事件的捕获呢?使用event.stopPropagation()方法吗?答案是否定的,这里要知道,stopPropagation()方法只能阻止事件的冒泡,而不能阻止事件捕获。

但是我们可以使用DOM3级新增事件stopImmediatePropagation()方法来阻止事件捕获,另外此方法还可以阻止事件冒泡。应用如下:

document.getElementById("second").addEventListener("click",function(){
 alert("second");
 event.stopImmediatePropagation();
},true);

这样,就可以在id为second处阻止事件的捕获了。

注意:尽管这是Netscape Navigator提出的事件流,但是现在所有的浏览器都支持这种事件流模型。但是由于老的浏览器不支持,所以很少有人使用事件捕获。

  第三部分:DOM事件流

DOM2级事件规定的时间流包括 三个阶段:

  • 事件捕获阶段
  • 处于目标阶段
  • 事件冒泡阶段

注意:在DOM事件流中,实际的目标在捕获阶段不会接收到事件,下一个阶段是处于目标阶段,这时事件被触发,最后进入事件冒泡阶段。我们认为处于目标阶段是事件冒泡阶段的一部分。

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
一些常用且实用的原生JavaScript函数
Sep 08 Javascript
jquery实现清新实用的网页菜单效果
Aug 28 Javascript
Javascript函数式编程语言
Oct 11 Javascript
如何使用jquery easyui创建标签组件
Nov 18 Javascript
jquery中checkbox使用方法简单实例演示
Nov 24 Javascript
js正则表达式注册页面表单验证
Oct 11 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
Feb 08 Javascript
Node.js使用NodeMailer发送邮件实例代码
Mar 06 Javascript
Bootstrap布局之栅格系统学习笔记
May 04 Javascript
vue-router路由参数刷新消失的问题解决方法
Jun 17 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
Sep 01 Javascript
JavaScript选择器函数querySelector和querySelectorAll
Nov 27 Javascript
JS基于正则截取替换特定字符之间字符串操作示例
Feb 03 #Javascript
几种tab切换详解
Feb 03 #Javascript
Bootstrap页面缩小变形的快速解决办法
Feb 03 #Javascript
拖动时防止选中
Feb 03 #Javascript
jQuery表格的维护和删除操作
Feb 03 #Javascript
折叠菜单及选择器的运用
Feb 03 #Javascript
jQuery读取XML文件的方法示例
Feb 03 #Javascript
You might like
php的正则处理函数总结分析
2008/06/20 PHP
php处理restful请求的路由类分享
2014/02/27 PHP
PHP实现算式验证码和汉字验证码实例
2015/03/09 PHP
php提供实现反射的方法和实例代码
2019/09/17 PHP
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
js 强制弹出窗口代码研究-又一款代码
2010/03/20 Javascript
用原生JavaScript实现jQuery的$.getJSON的解决方法
2013/05/03 Javascript
使用delegate方法为一个tr标签加一个链接
2014/06/27 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
AngularJS 整理一些优化的小技巧
2016/08/18 Javascript
详解JavaScript跨域总结与解决办法
2016/10/31 Javascript
微信小程序实战之上拉(分页加载)效果(2)
2017/04/17 Javascript
vue动态路由配置及路由传参的方式
2018/05/23 Javascript
js+html实现点名系统功能
2019/11/05 Javascript
js表达式与运算符简单操作示例
2020/02/15 Javascript
vue实现短信验证码输入框
2020/04/17 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
wxPython窗口中文乱码解决方法
2014/10/11 Python
Python代码调试的几种方法总结
2015/04/15 Python
Python使用django获取用户IP地址的方法
2015/05/11 Python
利用numpy和pandas处理csv文件中的时间方法
2018/04/19 Python
numpy判断数值类型、过滤出数值型数据的方法
2018/06/09 Python
详解python3中的真值测试
2018/08/13 Python
python bmp转换为jpg 并删除原图的方法
2018/10/25 Python
巴西手表购物网站:eclock
2019/03/19 全球购物
七一党建活动方案
2014/01/28 职场文书
安全检查管理制度
2014/02/02 职场文书
应届毕业生通用的自荐书范文
2014/02/07 职场文书
监察建议书范文
2014/03/12 职场文书
高校群众路线教育实践活动剖析材料
2014/10/10 职场文书
2014年度安全工作总结
2014/12/04 职场文书
青岛导游词
2015/02/12 职场文书
2015年学校远程教育工作总结
2015/07/20 职场文书
python 爬取哔哩哔哩up主信息和投稿视频
2021/06/07 Python
Go语言读取txt文档的操作方法
2022/01/22 Golang