JavaScript事件:事件处理模型(冒泡、捕获)、取消冒泡、阻止默认事件
(一)事件处理模型---事件冒泡、捕获
(1)事件冒泡
24 <body>
25 <div class="warpper">
26 <div class="content">
27 <div class="box">
28
29 </div>
30 </div>
31 </div>
32 <script type="text/javascript">
33 var warpper = document.getElementsByClassName('warpper')[0];
34 var content = document.getElementsByClassName('content')[0];
35 var box = document.getElementsByClassName('box')[0];
36
37 warpper.addEventListener('click',function(){
38 console.log("warpper-red");
39 },false)
40 content.addEventListener('click',function(){
41 console.log('content-yellow');
42 },false)
43 box.addEventListener('click',function(){
44 console.log('box-bule');
45 },false)
46
47 </script>
48
49 </body>
如下:点击蓝色区域,三个div都会相应click事件
(2)事件捕获
1 warpper.addEventListener('click',function(){
2 console.log("warpper-red");
3 },true)
4 content.addEventListener('click',function(){
5 console.log('content-yellow');
6 },true)
7 box.addEventListener('click',function(){
8 console.log('box-bule');
9 },true)
点击蓝色区域,会先父级元素捕获到,然后在子元素;
(3)触发顺序:先捕获 后冒泡
1 warpper.addEventListener('click',function(){
2 console.log("warpper-red,Bubble");
3 },false)
4 content.addEventListener('click',function(){
5 console.log('content-yellow,Bubble');
6 },false)
7 box.addEventListener('click',function(){
8 console.log('box-bule,Bubble');
9 },false)
10
11 warpper.addEventListener('click',function(){
12 console.log("warpper-red");
13 },true)
14 content.addEventListener('click',function(){
15 console.log('content-yellow');
16 },true)
17 box.addEventListener('click',function(){
18 console.log('box-bule');
19 },true)
***********************************************************************************************************************************************
(二)阻止事件冒泡
(1)取消冒泡
先看示例:
1 <body>
2 <div style="width:100px;height:100px;background-color:red">
3 </div>
4 <script type="text/javascript">
5 var div = document.getElementsByTagName('div')[0];
6
7 document.onclick = function(){
8 console.log('没事别点我-document');
9 }
10
11 div.onclick =function(){
12 console.log("click-div");
13 }
14 </script>
15
16 </body>
由于我们在document上绑定了click事件,所以当我们点击红色的div时,由于冒泡问题,document的click事件也是会被触发;
那如何来实现,当我们点击div时,只想让div相应对应的处理事件,而document不响应呢;
那就是取消冒泡事件;
(1) 方法1: event.stopPropagation(); //IE9以下不支持
说明:在事件处理函数可以设置一个形参,这个参数我们自己用不到,但是系统会传一个event过来;
1 <script type="text/javascript">
2 var div = document.getElementsByTagName('div')[0];
3
4 document.onclick = function(){
5 console.log('没事别点我-document');
6 }
7
8 div.onclick =function(event){
9 event.stopPropagation();
10 console.log("click-div");
11 }
12 </script>
(2) 方法2:enent.cancelBubble(); //IE独有
1 <script type="text/javascript">
2 var div = document.getElementsByTagName('div')[0];
3
4 document.onclick = function(){
5 console.log('没事别点我-document');
6 }
7
8 div.onclick =function(event){
9 event.cancelBubble = true;
10 console.log("click-div");
11 }
12 </script>
(3)针对取消冒泡的原生系统函数存在兼容性问题,我们自己来封装一个好的兼容性函数:
1 <script type="text/javascript">
2 var div = document.getElementsByTagName('div')[0];
3
4 document.onclick = function(){
5 console.log('没事别点我-document');
6 }
7
8 div.onclick =function(event){
9 stopBubble(event);
10 console.log("click-div");
11 }
12
13 function stopBubble(event){
14 if(event.stopProgration){
15 event.stopProgration();
16 }else{
17 event.cancelBubble = true;
18 }
19 }
21 </script>
***********************************************************************************************************************************************
(三)阻止默认事件
以标签a为例,当点击a标签时,默认都是跳转的动作,这个就是默认事件;
(1) event.preventdefault()
1 <body>
2 <div>
3 <a href="#">我是个a标签</a>
4 </div>
5 <script type="text/javascript">
6 var div = document.getElementsByTagName('div')[0];
7 var a = document.getElementsByTagName('a')[0];
8
9 div.addEventListener('click',function(e){
10 console.log('click-div');
11 },false);
12 a.addEventListener('click',function(e){
13 // e.preventDefault();
14 console.log('click-a');
15 },false);
16 </script>
17
18 </body>
1 a.addEventListener('click',function(e){
2 e.preventDefault();
3 console.log('click-a');
4 },false);
(2) e.returnValue = false;
1 a.addEventListener('click',function(e){
2 // e.preventDefault();
3 e.returnValue = false;
4 console.log('click-a');
5 },false);
同样也是可以阻止默认事件,即点a跳转问题;
(3) 兼容性问题。自己封装函数:
1 function cancelDefaulthandle(event){
2 if(event.preventDefault){
3 event.preventDefault();
4 }else{
5 event.returnValue = false;
6 }
7 }
(4) return false方法阻止默认事件:
这个方法比较暴力,他会同事阻止事件冒泡也会阻止默认事件;写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;可以理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault();
1 <script type="text/javascript">
2 var div = document.getElementsByTagName('div')[0];
3 var a = document.getElementsByTagName('a')[0];
4
5 div.onclick = function(){
6 console.log('click-div');
7 }
8
9 a.onclick = function(){
10 console.log('click-1a');
11 }
12 </script>
上述代码,点击a标签,实际干了三件事情,先后为 执行本身处理函数、冒泡父级处理函数,接着响应默认事件(跳转);
1 <script type="text/javascript">
2 var div = document.getElementsByTagName('div')[0];
3 var a = document.getElementsByTagName('a')[0];
4
5 div.onclick = function(){
6 return false;
7 console.log('click-div');
8 }
9
10 a.onclick = function(){
11 console.log('click-1a');
12 }
13 </script>
要想,既阻止默认事件又阻止冒泡事件,return false必须加在父级处理函数里面;