JS中的事件冒泡(Bubble)和事件捕获(capture)以及如何阻止事件的冒泡
对“捕获”和“冒泡”这两个概念,通常我们对冒泡了解和使用的会更多一些,因为在我们使用的所有浏览器中,都支持事件冒泡 ,即事件由子元素向祖先元素传播的,就 像气泡从水底向水面上浮一样。而在像firefox,chrome,safari这类所谓的标准浏览器中,事件传播通常是有三个阶段的:事件捕获阶段,事 件目标阶段,事件冒泡阶段,这三者的执行的顺序是先捕获在冒泡。对于捕获阶段,这个很少 有用武之地,所以被人疏忽遗忘也在所难免了,不常用不代表它不存在,本着科学严谨的态度,我们有必要去看一下它的庐山真面目。
事件冒泡:事 件冒泡指的是当前的目标元素触发事件的发生,事件在一次向祖先元素传播,在祖先元素上触发相同类型的事件。当子元素都有同一事件处理程序时,利用事件的冒 泡可以减少代码的冗余度。通过给元素对象绑定事件的方法addEventlistener()第三个参数决定事件的执行阶段是在冒泡阶段还是捕获阶段,当 第三个参数为false时,为冒泡阶段,通常省略该参数是默认的是冒泡,如果为true则是捕获阶段。为了兼容IE8以及IE8之前版本浏览器可以通过 attachEvent()方法给元素添加事件不过他没有第三个参数。下面的例子是没有阻止事件冒泡时的代码,最终会看到,当点击了ele2时,事件会向 上冒泡依次输出ele2,ele,ele0,这个就是由于事件的冒泡引起的。
1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>bubble event</title>
5 <style>
6 .ele0{
7 width:400px;
8 height:400px;
9 border:1px solid black;
10 background-color:red;
11 position:relative;
12 }
13 .ele1{
14 width:300px;
15 height:300px;
16 border:1px ;
17 background-color:green;
18 position:absolute;
19 top:0;
20 }
21 .ele2{
22 width:200px;
23 height:200px;
24 border:1px ;
25 background-color:blue;
26 position:absolute;
27 top:0;
28 }
29 </style>
30 <script>
31 window.onload=function(){
32 var ele=document.getElementsByTagName("div");
33
34 if(ele[0].addEventListener)
35 {
36 ele[0].addEventListener("click", function (){
37
38 console.log("点击的是盒子ele0!");
39 });
40 }
41
42 else{
43 ele[0].attachEvent("onclick",function (){
44 console.log("点击的是盒子ele0!");
45
46 });
47 }
48 if(ele[1].addEventListener)
49 {
50 ele[1].addEventListener("click", function (){
51
52 console.log("点击的是盒子ele1!");
53 });
54 }
55
56 else{
57 ele[1].attachEvent("onclick",function (){
58 console.log("点击的是盒子ele1!");
59
60 });
61 }
62
63 if(ele[2].addEventListener)
64 {
65 ele[2].addEventListener("click", function (){
66
67 console.log("点击的是盒子ele2!");
68 });
69 }
70
71 else{
72 ele[2].attachEvent("onclick",function (){
73 console.log("点击的是盒子ele2!");
74
75 });
76 }
77
78 }
79 </script>
80 </head>
81 <body>
82 <div class="ele0">
83 <div class="ele1"><div class="ele2"></div></div>
84
85 </div>
86 </body>
87 <html>
事件捕获:事 件捕获过程与事件的冒泡阶段是一个相反的阶段,即事件由祖先元素向子元素传播,和一个石子儿从水面向水底下沉一样,要说明的是在 IE,opera浏览器中,是不存在这个阶段的。在上述的代码中给事件监听程序添加第三个参数false,当点击元素ele2时会看到不一样的效果,输出 结果中将会最先输出ele0,而不是ele2,这就是事件的捕获。
阻止事件的冒泡:
有时候事件的冒泡回会导致程序的运行顺序和自己想象的情形不一样,这时候就需要对事件的冒泡进行阻止。阻止事件的冒泡的方法与事件处理程序的添加方式有关:
1. 在除IE以外其他的浏览器中通过e.stopPropagation()方式阻止事件的冒泡。在 支持该方法的浏览器中还有一个方法stopimmediatePropagation(),该方法不仅会组织事件向祖元素的冒泡,同时也会阻止同一个节点 上同一事件的其他的事件处理程序的执行,该方法比前者阻止的更彻底。
2.在IE浏览器中通过e.cancleBubble=true,阻止事件冒泡。
1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>bubble event</title>
5 <style>
6 .ele0{
7 width:400px;
8 height:400px;
9 border:1px solid black;
10 background-color:red;
11 position:relative;
12 }
13 .ele1{
14 width:300px;
15 height:300px;
16 border:1px ;
17 background-color:green;
18 position:absolute;
19 top:0;
20 }
21 .ele2{
22 width:200px;
23 height:200px;
24 border:1px ;
25 background-color:blue;
26 position:absolute;
27 top:0;
28 }
29 </style>
30 <script>
31 window.onload=function(){
32 var ele=document.getElementsByTagName("div");
33
34 if(ele[0].addEventListener)
35 {
36 ele[0].addEventListener("click", function (e){
37
38 console.log("点击的是盒子ele0!");
39 e.stopPropagation();
40 });
41
42 }
43
44 else{
45 ele[0].attachEvent("onclick",function (e){
46 console.log("点击的是盒子ele0!");
47 e=window.event;
48 e.cancleBubble=true;
49
50 });
51 }
52 if(ele[1].addEventListener)
53 {
54 ele[1].addEventListener("click", function (e){
55
56 console.log("点击的是盒子ele1!");
57 e.stopPropagation();
58 });
59 }
60
61 else{
62 ele[1].attachEvent("onclick",function (e){
63 console.log("点击的是盒子ele1!");
64 e=window.event;
65 e.cancleBubble=true;
66
67 });
68 }
69
70 if(ele[2].addEventListener)
71 {
72 ele[2].addEventListener("click", function (e){
73
74 console.log("点击的是盒子ele2!");
75 e.stopPropagation();
76 });
77 }
78
79 else{
80 ele[2].attachEvent("onclick",function (e){
81 console.log("点击的是盒子ele2!");
82 e=window.event;
83 e.cancleBubble=true;
84
85 });
86 }
87
88 }
89 </script>
90 </head>
91 <body>
92 <div class="ele0">
93 <div class="ele1"><div class="ele2"></div></div>
94
95 </div>
96 </body>
97 <html>
阻止事件的默认行为:
1、在IE浏览器中通过e.returnValue=false
2、在其他浏览器中调用方法e.preventDefault();
3、在jQuery中通过在事件回调利用return false(其实质利用了上面的两种方式)实现阻止事件的默认行为