zoukankan      html  css  js  c++  java
  • 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{   /*为了直观 这里添加些样式*/
           300px;
          height: 200px;
          background-color: red;
        }
        #dv2{
           250px;
          height: 150px;
          background-color: green;
        }
        #dv3{
           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 {
           300px;
          height: 200px;
          background-color: red;
        }
    
        #dv2 {
           250px;
          height: 150px;
          background-color: green;
        }
    
        #dv3 {
           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)
    
  • 相关阅读:
    java @param参数注解
    java 泛型类
    HttpServletRequestWrapper的使用
    java工具类系列 (四.SerializationUtils)
    spring aop通过joinpoint传递参数
    java retention注解
    stringUtils是apache下的Java jar补充包
    slf4j日志系统
    支付宝支付接口开发
    wifi定位原理
  • 原文地址:https://www.cnblogs.com/qdhxhz/p/12025089.html
Copyright © 2011-2022 走看看