随笔 - 416  文章 - 0  评论 - 842  阅读 - 273万

JavaScript(3)---事件冒泡、事件捕获

JavaScript(3)---事件冒泡与事件捕获

一、理解冒泡与捕获

假设有这么一段代码

<body>
  <div><p>标签</p>
  </div>
</body>

转换成图如下

我们知道Dom是有节点关系的

body -> div -> p 之间的关系就是  爷爷 -> 父亲 -> 儿子。

我们来思考一个关键的问题

如果此时我们在 body div p 都绑定一个点击事件(click)。此时如果我们只点击 p标签,它会不会触发div绑定事件body绑定事件

答案是会的

那这个时候就会有一个问题,既然点击 p标签 会触发 div绑定事件body绑定事件,那执行顺序是怎么样的呢?

body事件 -> div事件 -> p事件? 还是  p事件  -> div事件 -> body事件?

这两种不同的执行顺序就是对应上面的 事件冒泡事件捕获

事件捕获 事件从最上一级标签开始往下查找,直到捕获到事件目标(body事件 -> div事件 -> p事件)。

事件冒泡 事件从事件目标开始,往上冒泡直到页面的最上一级标签( p事件 -> div事件 -> body事件)

为了不混淆记忆它们,这里有个通俗的理解冒泡:

冒泡嘛,就像水里往上冒的泡泡,从一开始很小,然后慢慢变大直到破裂。所以是从小到大,也就是子标签到父标签传递的过程。那么事件捕获记住与冒泡相反就可以了。


二、事件冒泡 与 阻止冒泡

1、事件冒泡示例

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件冒泡</title>
  <style>
    #dv1{   /*为了直观 这里添加些样式*/
      width: 300px;
      height: 200px;
      background-color: red;
    }
    #dv2{
      width: 250px;
      height: 150px;
      background-color: green;
    }
    #dv3{
      width: 200px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>

<body>
<div id="dv1">爷爷
  <div id="dv2">父亲
    <div id="dv3">儿子</div>
  </div>
</div>
<script>
  //事件冒泡:多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面的元素的该事件自动的触发了.
  document.getElementById("dv1").onclick=function () {
    console.log(this.id+" 爷爷");
  };
  document.getElementById("dv2").onclick=function () {
    console.log(this.id+" 父亲");
  };
  //事件处理参数对象
  document.getElementById("dv3").onclick=function (e) {
    console.log(this.id+" 儿子");
    //阻止事件冒泡
    //e.stopPropagation();
  };
</script>
</body>
</html>

运行结果

从这个示例我们可以看出3点

1、当点击儿子元素后,父亲和爷爷的点击事件也触发了。
2、onclick事件的顺序 儿子 - 父亲 - 爷爷。
3、当点击爷爷元素后,父亲和儿子的点击是不会触发的。

2、阻止事件冒泡

既然有冒泡事件,那肯定在实际开放过程中,你不需要冒泡,你只想儿子点击触发事件,父亲和爷爷不触发事件。

语法

1、window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持
2、e.stopPropagation(); 谷歌和火狐支持

因为我用的是谷歌浏览器,所以这里用第二种方式阻止冒泡(只需把上面阻止事件冒泡的代码取消注释就可以了)

运行结果

从运行结果很明显看出,已经阻止了事件冒泡。


三、事件捕获

示例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <style>
    #dv1 {
      width: 300px;
      height: 200px;
      background-color: red;
    }

    #dv2 {
      width: 250px;
      height: 150px;
      background-color: green;
    }

    #dv3 {
      width: 200px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>

<body>
<div id="dv1">爷爷
  <div id="dv2">父亲
    <div id="dv3">儿子</div>
  </div>
</div>
<script>
    //为每个元素绑定事件  这里
    /**
     * 捕获时间 从外到里
     * 1、 addEventListener不是每个浏览器都兼容的
     * 2、 这里true为事件捕获 false为事件冒泡
     */
     document.getElementById("dv1").addEventListener("click", function (e) {
         console.log(this.id+" 爷爷");
    }, true);
   document.getElementById("dv2").addEventListener("click", function (e) {
         console.log(this.id+" 父亲");
    }, true);
      document.getElementById("dv3").addEventListener("click", function (e) {
         console.log(this.id+" 儿子");
    }, true);
</script>
</body>
</html>

运行

很明显,这里是从外到里执行事件。


你如果愿意有所作为,就必须有始有终。(22)
posted on   雨点的名字  阅读(496)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

点击右上角即可分享
微信分享提示

目录导航