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


Posted in Javascript onDecember 07, 2016

事件流描述的是从页面中接收事件的顺序。提出事件流概念的正是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 学习笔记(十一)
Jan 19 Javascript
js如何判断用户是在PC端和还是移动端访问
Apr 24 Javascript
JavaScript检查数字是否为整数或浮点数的方法
Jun 09 Javascript
js漂浮广告实现代码
Aug 15 Javascript
第十篇BootStrap轮播插件使用详解
Jun 21 Javascript
jQuery简单动画变换效果实例分析
Jul 04 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
Apr 04 Javascript
Vue form 表单提交+ajax异步请求+分页效果
Apr 22 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
Vue父组件调用子组件事件方法
Feb 23 Javascript
Vue 监听列表item渲染事件方法
Sep 06 Javascript
详解Vue template 如何支持多个根结点
Feb 10 Javascript
纯JS焦点图特效实例(可一个页面多用)
Dec 07 #Javascript
探究JavaScript中的五种事件处理程序方式
Dec 07 #Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
Dec 07 #Javascript
jquery插入兄弟节点的操作方法
Dec 07 #Javascript
Bootstrap基本样式学习笔记之表格(2)
Dec 07 #Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
Dec 07 #Javascript
Bootstrap学习笔记之环境配置(1)
Dec 07 #Javascript
You might like
php 需要掌握的东西 不做浮躁的人
2009/12/28 PHP
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
php fsockopen伪造post与get方法的详解
2013/06/14 PHP
使用PHP实现阻止用户上传成人照片或者裸照
2014/12/25 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
PHP页面静态化――纯静态与伪静态用法详解
2020/06/05 PHP
Mootools 1.2教程 排序类和方法简介
2009/09/15 Javascript
JS中表单的使用小结
2014/01/11 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
2015/08/21 Javascript
举例讲解JavaScript中关于对象操作的相关知识
2015/11/16 Javascript
JS iFrame加载慢怎么解决
2016/05/13 Javascript
Vuejs第十篇之vuejs父子组件通信
2016/09/06 Javascript
轻松实现js弹框显示选项
2016/09/13 Javascript
Javascript中this绑定的3种方法与比较
2016/10/13 Javascript
javascriptvoid(0)含义以及与&quot;#&quot;的区别讲解
2019/01/19 Javascript
Android 自定义view仿微信相机单击拍照长按录视频按钮
2019/07/19 Javascript
vue路由结构可设一层方便动态添加路由操作
2020/08/31 Javascript
教你安装python Django(图文)
2013/11/04 Python
python模拟Django框架实例
2016/05/17 Python
Django migrations 默认目录修改的方法教程
2018/09/28 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
2020/05/20 Python
python的flask框架难学吗
2020/07/31 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
详解webapp页面滚动卡顿的解决办法
2018/12/26 HTML / CSS
英国第二大营养品供应商:Vitabiotics
2016/10/01 全球购物
中专生自我鉴定范文
2013/12/19 职场文书
会计大学生职业生涯规划书范文
2014/01/13 职场文书
党支部书记岗位责任制
2014/02/11 职场文书
销售员求职个人的自我评价
2014/02/19 职场文书
爱情寄语大全
2014/04/09 职场文书
领导干部群众路线对照检查材料
2014/11/05 职场文书
毕业证明模板
2015/06/19 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
总经理聘用协议书
2015/09/21 职场文书
三严三实·严以用权心得体会
2016/01/12 职场文书
Redis遍历所有key的两个命令(KEYS 和 SCAN)
2021/04/12 Redis