JavaScript事件机制——细思极恐

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

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

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

3. 冒泡可以阻止,那捕获可以阻止吗?java

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

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

示例spa

<!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解释为“指定事件是否在捕获或冒泡阶段执行”,我以为这个说明会让人误会,搞得像捕获或冒泡均可以不选的样子。但其实不是,只是二选一,因此最好解释为“指定事件是在捕获阶段仍是冒泡阶段执行”。.net

定义code

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

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

相关文章
相关标签/搜索