• JavaScript事件机制——细思极恐


    JavaScript事件机制,也有让人深思的东西。在一开始未深入了解,我头脑里有几个问题发出:

    1. 自下而上(冒泡)事件怎么写,自上而下(捕获)又是怎么写?

    2. 捕获型和冒泡型同时设置,谁生效?

    3. 冒泡能够阻止,那捕获能够阻止吗?

    4. jquery的on或bind是冒泡,还是捕获?

    5. 两种事件方式的应用场景是?

    示例

    <!DOCTYPE HTML>
    <html lang="en-US">
    <head>
    <meta charset="UTF-8"/>
    <title>Events</title>
    <script type="text/javascript" src="jquery-3.0.0.js"></script>
    <style>
         html,body{
              width:100%;
              height:100%;
              padding: 0;
              margin: 0;
         }
         div{
              float:left;
              width: 200px;
              height:200px;
              border:1px solid blue;
         }
         p{
              width: 100px;
              height:100px;
              border:1px solid red;
         }
    </style>
    </head>
         <body id="body">
              <div id="J_d0">
                   0<p id="J_p0"></p>
              </div>
              <div id="J_d1">
                   1<p id="J_p1"></p>
              </div>
              <div id="J_d2">
                   2<p id="J_p2"></p>
              </div>
              <div id="J_d3">
                   3<p id="J_p3"></p>
              </div>
              <div id="J_d4">
                   4<p id="J_p4"></p>
              </div>
         </body>
         <script>
              var body = document.getElementById('body');
              body.addEventListener('click', hello, true); //当为false时,全部在最后执行。
     
              bindEvent_d_p(0,true,true);
              //点击p,输出
              //i am body
              //i am J_d0
              //i am J_p0
     
              bindEvent_d_p(1,false,true);
              //点击p,输出
              //i am body
              //i am J_p1
              //i am J_d1
     
              bindEvent_d_p(2,false,false);
              //点击p,输出
              //i am body
              //i am J_p2
              //i am J_d2
     
              bindEvent_d_p(3,true,false);
              //点击p,输出
              //i am body
              //i am J_d3
              //i am J_p3
     
              $("#J_d4").on("click", hello);
              $("#J_p4").on("click", hello);
              //点击p,输出
              //i am body
              //i am J_p4
              //i am J_d4
     
              function bindEvent_d_p(index, d_useCapture, p_useCapture){
                   var d = document.getElementById('J_d'+index);
                   var p = document.getElementById('J_p'+index);
                   
    //第三个参数,指定事件是在捕获阶段还是冒泡阶段执行。
    d.addEventListener('click', hello, d_useCapture);
    p.addEventListener('click', hello, p_useCapture);
              }
              function hello() {
                   console.log("i am " + this.id);
              }
         </script>
    </html>

    这里关键的是第三个参数。W3CSchool解释为“指定事件是否在捕获或冒泡阶段执行”,我觉得这个说明会让人误会,搞得像捕获或冒泡都可以不选的样子。但其实不是,只是二选一,所以最好解释为“指定事件是在捕获阶段还是冒泡阶段执行”。

    定义

    JavaScript的事件是以一种流(回环流)的形式存在的,一个事件会有多个元素同时响应。如下图:

    PS:图例来自http://www.nowamagic.net/javascript/js_EventAnalysis.php

    这个图非常清楚的说明的事件的执行顺序,完全可以解释示例中的结果。事件一直从window往触发目标元素流,当父或祖先捕获事件时,就先执行,不然就在冒泡阶段执行,直到window。

    Q&A

    1. 自下而上(冒泡)事件怎么写,自上而下(捕获)又是怎么写?

    当需要冒泡时,第三参数设为false就行;

    当需要捕获时,第三参数设为true就行;

    2. 捕获型和冒泡型同时设置,谁生效?

    按第三参数的设置,只有二选一,并不存在可以同时设置情况。

    3. 冒泡能够阻止,那捕获能够阻止吗?

    冒泡事件是能够阻止,e.stopPropagation();,大家是比较清楚的,同样的捕获事件也是能阻止的。

    其实就是当先触发的事件是在捕获过程的,阻止了事件传播,就是捕获阻止,当在冒泡过程中阻止,就是冒泡阻止。

    结果就是,事件流不再继续流了,无论是往下还是往上。

    4. jquery的on或bind是冒泡,还是捕获?

    经过上面示例可以验证, jquery的on或bind是冒泡执行的。

    另外在jquery3.0.0的源码4943行地方:

    // Init the event handler queue if we're the first
    if ( !( handlers = events[ type ] ) ) {
         handlers = events[ type ] = [];
         handlers.delegateCount = 0;
    
         // Only use addEventListener if the special events handler returns false
        if ( !special.setup ||
             special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
    
             if ( elem.addEventListener ) {
                   elem.addEventListener( type, eventHandle );
             }
        }
    }

    这里可以很明显看到,事件的注册并没有传第三个参数,所以 jquery的on或bind肯定是冒泡执行的。

    5. 两种事件方式的应用场景是?

    额,这个问题并不好回答,就具体问题,具体分析了。

    总结

    小小的往细处想,竟然发现我其实有些细节并没明白,共勉。


    本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

    本文地址 :http://www.cnblogs.com/lovesong/p/5705541.html

  • 相关阅读:
    什么是封装?
    table
    POM文件
    Maven环境的搭建
    什么是maven
    J2EE的三层经典结构
    DOM对象和jQuery对象对比
    jQuery常用选择器分类
    什么是JQuery?它的特点是什么?
    jQuery准备函数语法
  • 原文地址:https://www.cnblogs.com/lovesong/p/5705541.html
Copyright © 2020-2023  润新知