Triangel

生活除了诗和远方,还有油盐酱醋茶。

导航

关于事件捕获和事件冒泡

  这篇随笔主要是写关于事件冒泡和事件捕获的一些关联,主要是从《JavaScript高级程序设计》这本书第13章总结扩展而来,今天主要是想扩展对书本里面P358页以及加深一下理解。

一、先说下定义:

  事件冒泡阶段:从最具体的元素,即目标事件位置往文档的根节点方向回溯,从内向外冒泡事件对象(所有浏览器都支持)。

  事件捕获阶段:先由文档的根节点document往事件触发对象,从外向内捕获事件对象(DOM2级事件要求事件从document对象开始传播,但是IE9,Safari,Chrome,Opera,Firefox都是从window对象开始捕获事件的,老版本的浏览器不支持事件捕获)。

  目标阶段:到达被触发的元素。

  事件处理程序是否指定给目标元素怎么看?如果触发的函数直接绑定在目标元素上面的话,那么事件处理程序就是直接指定给目标元素。在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实 际目标。如下面的代码:

  (1)事件处理程序就是直接指定给目标元素

  <input type="button" value="点击" id="btn">

  var btn = document.getElementById("btn");

  btn.onclick = function(){   //红色部分就是事件处理程序,假设我们此时点击按钮,那么此时事件处理程序直接指定给目标元素id为btn的按钮

    console.log(event.currentTarget === this);   //true,此时this,currentTarget,target的值都相同

    console.log(event.target === this); //true

  }

  (2)事件处理程序就是未直接指定给目标元素  

  <input type="button" value="点击" id="btn">

  var btn = document.getElementById("btn");

  document.body.onclick = function(){   //假设我们此时点击按钮,那么此时事件处理程序是指定给body

    console.log(event.currentTarget === document.body);   //true,此时this,currentTarget的值都相同

    console.log(this === document.body); //true

    console.log(event.target === document.getElementById("btn")); //true

  }

二、"DOM2级事件"规定事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。首先是事件捕获(此时可以截获事件);然后就是实际的目标接收到事件;最后就是冒泡阶段,可以再这个阶段对事件作出响应。

(此图片来源百度图片)

  接下来就是扩展的问题啦啦啦啦,集中精神。

  1.先单独看一下冒泡和捕获的过程

  (1)冒泡过程:

  代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         *{
 7             font-size: 20px;
 8             color: white;
 9         }
10         #one{
11             width: 400px;
12             height: 400px;
13             background-color: pink;
14         }
15         #two{
16             width: 300px;
17             height: 300px;
18             background-color: green;
19         }
20         #three{
21             width: 200px;
22             height: 200px;
23             background-color: blue;
24         }
25         #four{
26             width: 100px;
27             height: 100px;
28             background-color: black;
29         }
30     </style>
31     <script type="text/javascript">
32         window.onload = function(){
33           var one=document.getElementById('one');
34           var two=document.getElementById('two');
35           var three=document.getElementById('three');
36           var four=document.getElementById('four');
37           one.addEventListener('click',function(){
38             console.log('one冒泡');
39           },false);
40           two.addEventListener('click',function(){
41             console.log('two冒泡');
42           },false);
43           three.addEventListener('click',function(){
44             console.log('three冒泡');
45           },false);
46           four.addEventListener('click',function(){
47             console.log('four冒泡');
48           },false);
49         }
50     </script>
51 </head>
52 <body>
53     <div id='one'>
54         one
55           <div id='two'>
56               two
57             <div id='three'>
58                 three
59                   <div id='four'>
60                       four
61                   </div>
62             </div>
63           </div>
64     </div>
65 </body> 
66 </html>
View Code

  效果图:

  

  (2)捕获过程:

  代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         *{
 7             font-size: 20px;
 8             color: white;
 9         }
10         #one{
11             width: 400px;
12             height: 400px;
13             background-color: pink;
14         }
15         #two{
16             width: 300px;
17             height: 300px;
18             background-color: green;
19         }
20         #three{
21             width: 200px;
22             height: 200px;
23             background-color: blue;
24         }
25         #four{
26             width: 100px;
27             height: 100px;
28             background-color: black;
29         }
30     </style>
31     <script type="text/javascript">
32         window.onload = function(){
33           var one=document.getElementById('one');
34           var two=document.getElementById('two');
35           var three=document.getElementById('three');
36           var four=document.getElementById('four');
37           one.addEventListener('click',function(){
38             console.log('one捕获');
39           },true);
40           two.addEventListener('click',function(){
41             console.log('two捕获');
42           },true);
43           three.addEventListener('click',function(){
44             console.log('three捕获');
45           },true);
46           four.addEventListener('click',function(){
47             console.log('four捕获');
48           },true);
49         }
50     </script>
51 </head>
52 <body>
53     <div id='one'>
54         one
55           <div id='two'>
56               two
57             <div id='three'>
58                 three
59                   <div id='four'>
60                       four
61                   </div>
62             </div>
63           </div>
64     </div>
65 </body> 
66 </html>
View Code

  效果图: 

 

  2.既有捕获又有冒泡时的过程:

  代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         *{
 7             font-size: 20px;
 8             color: white;
 9         }
10         #one{
11             width: 400px;
12             height: 400px;
13             background-color: pink;
14         }
15         #two{
16             width: 300px;
17             height: 300px;
18             background-color: green;
19         }
20         #three{
21             width: 200px;
22             height: 200px;
23             background-color: blue;
24         }
25         #four{
26             width: 100px;
27             height: 100px;
28             background-color: black;
29         }
30     </style>
31     <script type="text/javascript">
32         window.onload = function(){
33           var one=document.getElementById('one');
34           var two=document.getElementById('two');
35           var three=document.getElementById('three');
36           var four=document.getElementById('four');
37           one.addEventListener('click',function(){
38             console.log('one捕获');
39           },true);
40           two.addEventListener('click',function(){
41             console.log('two冒泡');
42           },false);
43           three.addEventListener('click',function(){
44             console.log('three捕获');
45           },true);
46           four.addEventListener('click',function(){
47             console.log('four冒泡');
48           },false);
49         }
50     </script>
51 </head>
52 <body>
53     <div id='one'>
54         one
55           <div id='two'>
56               two
57             <div id='three'>
58                 three
59                   <div id='four'>
60                       four
61                   </div>
62             </div>
63           </div>
64     </div>
65 </body> 
66 </html>
View Code

  效果图:

  

  3.如果一个元素同时绑定了两个事件,既有冒泡事件,又有捕获事件时,应该执行几次,先后顺序是什么?

  (1)绑定多少个事件就执行多少次事件。

  (2)执行顺序问题:

  【1】如果多次绑定事件的元素是目标元素,那么执行时就按照绑定的顺序执行(注意:这里说的按照绑定顺序执行是指利用addEventListener来绑定事件的;如果是利用attachEvent来绑定事件的,就是以绑定时的相反顺序执行),其他元素就按照先捕获后冒泡的顺序执行。

  代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         *{
 7             font-size: 20px;
 8             color: white;
 9         }
10         #one{
11             width: 400px;
12             height: 400px;
13             background-color: pink;
14         }
15         #two{
16             width: 300px;
17             height: 300px;
18             background-color: green;
19         }
20         #three{
21             width: 200px;
22             height: 200px;
23             background-color: blue;
24         }
25         #four{
26             width: 100px;
27             height: 100px;
28             background-color: black;
29         }
30     </style>
31     <script type="text/javascript">
32         window.onload = function(){
33           var one=document.getElementById('one');
34           var two=document.getElementById('two');
35           var three=document.getElementById('three');
36           var four=document.getElementById('four');
37           one.addEventListener('click',function(){
38             console.log('one捕获');
39           },true);
40           two.addEventListener('click',function(){
41             console.log('two冒泡');
42           },false);
43           three.addEventListener('click',function(){
44             console.log('three冒泡');
45           },false);
46           three.addEventListener('click',function(){
47             console.log('three捕获');
48           },true);
49           four.addEventListener('click',function(){
50             console.log('four冒泡');
51           },false);
52         }
53     </script>
54 </head>
55 <body>
56     <div id='one'>
57         one
58           <div id='two'>
59               two
60             <div id='three'>
61                 three
62                   <div id='four'>
63                       four
64                   </div>
65             </div>
66           </div>
67     </div>
68 </body> 
69 </html>
View Code

  

  【2】如果多次绑定事件的元素没有被触发,而是触发其他元素,那么多次绑定的元素的事件的执行顺序就是按照"DOM2级事件"规定的那样,先捕获,后目标元素,最后冒泡。

  代码同【1】中代码一样,只是这次是触发id为four这个div,效果图如下:

  

  OK,大概的扩展和进一步的理解就到这里,加油,在变得越来越优秀的路上,哈哈。

  

 

posted on 2016-05-05 21:30  Triangel  阅读(280)  评论(0编辑  收藏  举报