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中解析四则运算表达式的算法和示例
Aug 11 Javascript
浅谈jQuery中height与width
Jul 06 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
Feb 21 Javascript
JavaScript构建自己的对象示例
Nov 29 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
Mar 09 Javascript
Ionic2开发环境搭建教程
Aug 20 Javascript
JS实现留言板功能[楼层效果展示]
Dec 27 Javascript
Vue的H5页面唤起支付宝支付功能
Apr 18 Javascript
详解如何使用router-link对象方式传递参数?
May 02 Javascript
基于JS抓取某高校附近共享单车位置 使用web方式展示位置变化代码实例
Aug 27 Javascript
Vue项目页面跳转时浏览器窗口上方显示进度条功能
Mar 26 Javascript
Typescript3.9 常用新特性一览(推荐)
May 14 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
ThinkPHP控制器详解
2015/07/27 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
一个用js实现控制台控件的代码
2007/09/04 Javascript
JQuery动画和停止动画实例代码
2013/03/01 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
2013/12/19 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
浅谈jQuery事件绑定原理
2015/01/02 Javascript
教你使用javascript简单写一个页面模板引擎
2015/05/05 Javascript
通过实例理解javascript中没有函数重载的概念
2015/06/03 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
vue+Element实现搜索关键字高亮功能
2019/05/28 Javascript
vue绑定class的三种方法
2020/12/24 Vue.js
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
举例讲解Linux系统下Python调用系统Shell的方法
2015/11/07 Python
Python3的urllib.parse常用函数小结(urlencode,quote,quote_plus,unquote,unquote_plus等)
2016/09/18 Python
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
Python探索之ModelForm代码详解
2017/10/26 Python
EM算法的python实现的方法步骤
2018/01/02 Python
Python进度条实时显示处理进度的示例代码
2018/01/30 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
浅谈python中统计计数的几种方法和Counter详解
2019/11/07 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
从当地商店送来的杂货:Instacart
2018/08/19 全球购物
四好少年事迹材料
2014/01/12 职场文书
采购部长岗位职责
2014/06/13 职场文书
计算机应用专业自荐信
2014/07/05 职场文书
国际贸易系求职信
2014/08/09 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
回复函范文
2015/07/14 职场文书
2015年学校远程教育工作总结
2015/07/20 职场文书
2016入党培训心得体会范文
2016/01/08 职场文书
CSS 新特性 contain控制页面的重绘与重排问题
2021/04/30 HTML / CSS
CSS 制作波浪效果的思路
2021/05/18 HTML / CSS
html粘性页脚的具体使用
2022/01/18 HTML / CSS