事件冒泡学个透

简介: 事件冒泡学个透

事件冒泡,这一逻辑学名词对于很多初次学习JavaScript的程序员还是比较抽象,我想尝试用一种直观的方式,在这里将这个东西讲透。


首先我们去查看了事件冒泡的百度解释:


当事件发生后,这个事件就要开始传播(从里到外或者从外向里)。为什么要传播呢?因为事件源本身(可能)并没有处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上。例如我们点击一个按钮时,就会产生一个click事件,但这个按钮本身可能不能处理这个事件,事件必须从这个按钮传播出去,从而到达能够处理这个事件的代码中(例如我们给按钮的onclick属性赋一个函数的名字,就是让这个函数去处理该按钮的click事件),或者按钮的父级绑定有事件函数,当该点击事件发生在按钮上,按钮本身并无处理事件函数,则传播到父级去处理。


这一解释相对比较友好,但是难免还有些官方话。


到底该怎么理解呢?我们往下看:


我写一个简单框架:

                    <!-- 从父元素到子元素 -->
<body>                    <!-- 第一层 -->
  <div id="div1">             <!-- 第二层 -->
    <div id="div2">           <!-- 第三层 -->
      <div id="div3">         <!-- 第四层 -->
        <p>             <!-- 第五层 -->
          <span>          <!-- 第六层 -->
            事件冒泡
          </span>
        </p>
      </div>
    </div>
  </div>
</body>

接下来再为此框架设置简单的样式,样式呈现:然后我们给每一个元素设置点击事件:

    $(document).ready(function(){
      $("body").click(function(){
        alert("从外向内第一层");
      });
      $("#div1").click(function(){
        alert("从外向内第二层");
      });
      $("#div2").click(function(){
        alert("从外向内第三层");
      });
      $("#div3").click(function(){
        alert("从外向内第四层");
      });
      $("p").click(function(){
        alert("从外向内第五层");
      });
      $("span").click(function(){
        alert("从外向内第六层");
      });
    });

然后我们点击每个颜色不一样的元素,得到以下结果:

(青色)点击最外层body:出现弹出框‘从外向内第一层’


(绿色)点击div1:出现弹出框‘从外向内第二层’——‘从外向内第一层’


(黄色)点击div2:出现弹出框‘从外向内第三层’——‘从外向内第二层’——‘从外向内第一层’


(红色)点击div3:出现弹出框‘从外向内第四层’——‘从外向内第三层’——‘从外向内第二层’——‘从外向内第一层’


(蓝色)点击p标签:出现弹出框‘从外向内第五层’——‘从外向内第四层’——‘从外向内第三层’——‘从外向内第二层’——‘从外向内第一层’


(棕色)点击最内层span:出现弹出框‘从外向内第六层’——‘从外向内第五层’——‘从外向内第四层’——‘从外向内第三层’——‘从外向内第二层’——‘从外向内第一层’


程序员,这有什么规律,又说明什么?


你发现了,事件是由内向外触发的。正如事件冒泡名字本身一样形象,泡泡都是从水里开始出现,向水面移动,直到溢出水面爆炸,冒泡结束。


在编程语言里,程序也可以以这样的方式去执行。我们把这样由内向外触发事件的行为叫做事件冒泡。


一个理论的产生必定是要解决某些问题,否则,理论本身就没有意义了。那么,问题来了,这东西有什么用?


1.事件冒泡可以实现多个操作的集中处理,我们可以把事件添加到一个父级元素上,避免把同样的事件添加到多个子级元素上,它可以让你在对象层的不同级别捕获事件。


2.可让不同的元素执行同一个事件,并调用这个函数,按程序执行。


打个比方:你把自己想象成领导,你手底下有一群组员。你发命令,他们执行。


值得一提的是:


并非所有事件都可以冒泡,以下事件不会冒泡:blur、focus、load、unload。

事件冒泡是从里向外。还有从外到里的捕获事件。以及DOM事件流,先从外到里,再从里到外。(今天只研究事件冒泡,关于事件捕获,后续关注我博客。)

有了事件冒泡固然很好,但是如果我只想让冒泡事件出现一次,后面不想让它再冒泡,怎么办?


JavaScript考虑到了这一点,所以又出了一种阻止事件冒泡的方法,非常好用。


我发现了一种对初学js的程序员比较友好的描述:


通常情况下我们都是一步到位,明确自己的事件触发源,并不希望浏览器自作聪明、漫无目的地去帮我们找合适的事件处理程序,即我们明确最精准目标,这种情况下我们不需要事件冒泡。另外通过对事件冒泡的理解,我们知道程序就像机器人,只要你不发号指令让它停下来,它就会一直重复执行,达不到我们想要的效果之外,这必然也增大了程序运行负担(这也牵扯到优化问题)。还有一个重要的问题是:事件冒泡处理可能会激活我们本来不想激活的事件,导致程序错乱,甚至无从下手调试,这常成为对事件冒泡原理不熟悉的程序员的棘手问题。所以必要时,我们一定要阻止事件冒泡。


一般地,阻止事件冒泡有这几种方法:

1.event.stopPropagation();

事件处理过程中,阻止了事件冒泡,但不会阻止默认行为

2.return false;

事件处理过程中,阻止了事件冒泡,也阻止了默认行为

3.event.preventDefault();

事件处理过程中,不阻止事件冒泡,但阻止默认行为


好了,在这我将完整代码上传,自己稍稍一研究,必定能搞明白时间冒泡是怎么回事。


关注我,后续更精彩!!!

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script type="text/JavaScript" src="./js/jquery-3.4.1.js"></script>
  <title>Document</title>
  <style>
    body{
      width: 500px;
      height: 500px;
      margin: 15vh 30vw;
      background-color: aqua;
      border: black solid 2px;
    }
    #div1{
      width: 400px;
      height: 400px;
      background-color: lawngreen;
    }
    #div2{
      width: 300px;
      height: 300px;
      background-color: yellow;
    }
    #div3{
      width: 200px;
      height: 200px;
      background-color: red;
    }
    p{
      width: 100px;
      height: 100px;
      background-color: blue;
    }
    span{
      background-color: brown;
      color: white;
    }
  </style>
  <script type="text/javascript">
    $(document).ready(function(){
      $("body").click(function(){
        alert("从外向内第一层");
      });
      $("#div1").click(function(){
        alert("从外向内第二层");
      });
      $("#div2").click(function(){
        alert("从外向内第三层");
      });
      $("#div3").click(function(){
        alert("从外向内第四层");
      });
      $("p").click(function(){
        alert("从外向内第五层");
      });
      $("span").click(function(){
        alert("从外向内第六层");
      });
    });
  </script>
</head>
                    <!-- 从父元素到子元素 -->
<body>                    <!-- 第一层 -->
  <div id="div1">             <!-- 第二层 -->
    <div id="div2">           <!-- 第三层 -->
      <div id="div3">         <!-- 第四层 -->
        <p>             <!-- 第五层 -->
          <span>          <!-- 第六层 -->
            事件冒泡
          </span>
        </p>
      </div>
    </div>
  </div>
</body>
</html>
相关文章
|
6月前
|
JavaScript
如何写事件冒泡和事件捕捉?
如何写事件冒泡和事件捕捉?
|
6月前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素传递,而事件捕获则从外层元素向内层传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。示例代码展示了如何设置。
49 2
|
17天前
|
JavaScript 前端开发 数据安全/隐私保护
事件捕获
【10月更文挑战第29天】事件捕获作为JavaScript中重要的事件传播机制之一,为开发者提供了一种在事件到达目标元素之前进行处理和控制的方式。通过合理地运用事件捕获,可以实现更灵活、更强大的事件处理逻辑,但同时也需要注意其兼容性、事件顺序和性能等方面的问题,以确保事件处理的正确性和高效性。
|
1月前
|
JavaScript 前端开发
事件冒泡和事件捕获的原理和区别
【10月更文挑战第15天】事件冒泡和事件捕获的原理和区别
|
2月前
|
存储 JavaScript 前端开发
js事件冒泡和事件委托
事件冒泡是指事件从最内层元素开始逐级向上传播至祖先元素的过程,默认情况下,点击子元素时会先触发自身的事件处理程序,再依次向上触发父元素的处理程序。事件委托则是在父元素上设置事件处理程序,利用事件冒泡机制处理子元素的事件,以此减少内存消耗和提高性能,特别适用于处理大量动态子元素的情况。其区别在于事件冒泡是事件传播机制的一部分,而事件委托是编程技巧,通过在父元素上绑定事件处理程序来简化子元素的事件处理。
25 0
|
6月前
|
JavaScript
|
6月前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素依次触发事件,而事件捕获则从最外层元素向内层元素传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。例如: ```javascript element.addEventListener(&#39;click&#39;, console.log, false); // 冒泡 element.addEventListener(&#39;click&#39;, console.log, true); // 捕获 ```
44 0
|
6月前
|
前端开发 JavaScript 容器
前端中的事件委托
前端中的事件委托
75 0
|
6月前
|
JavaScript
JS事件,你真的懂吗(捕获,冒泡)?
JS事件,你真的懂吗(捕获,冒泡)?
59 0
|
6月前
|
JavaScript
什么是事件冒泡?如何组织事件冒泡
什么是事件冒泡?如何组织事件冒泡
51 0