[JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
-->事件冒泡和捕获
-->事件监听
-->阻止事件传播
一、事件冒泡和捕获
1、概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的onclick事件也会被触发。js里称这种事件连续发生的机制为事件冒泡或者事件捕获。
IE浏览器:事件从里向外发生,事件从最精确对象(target)开始触发,然后到最不精确的对象(document)触发,即事件冒泡
Netscape:事件从外向里发生,事件从最不精确的对象(document)开始触发,然后到最精确对象(target)触发,
即事件捕获
2、W3C标准将两者进行中和,在任何的W3C的事件模型中,
事件先进入捕获阶段,再进入冒泡阶段
3、一般的绑定事件方式
div1.onclick=function () {
alert('div被点击');
};
在一个支持W3C DOM的浏览器中,一般的绑定事件方式,采用的是事件冒泡方式
程序员可以选择绑定事件时采用事件捕获还是事件冒泡,
办法就是绑定事件时通过addEventListener( )方法
二、事件监听
1、支持W3C标准的浏览器在绑定事件时可以用addEventListener(type,fn,useCapture) 方法
参数:type----------事件类型,例:click
fn--------------事件处理函数
useCapture----布尔值true或false
( true表示事件捕获,false表示事件冒泡 )
为了兼容浏览器,第三个参数一般设置为false
事件监听:addEventListener(type,fn,useCapture)
事件移除:removeEventListener(type, fn, useCapture)
2、因为IE678只支持事件冒泡,不支持事件捕获,所以它也不支持addEventListener( )方法,IE提供了另一个函数:
attachEvent( type , fn )
参数:type---------事件类型,例:onclick
fn-------------事件处理函数
没有第三个参数
事件监听:attachEvent( type , fn )
事件移除:detachEvent( type , fn )
三、阻止事件传播
事件冒泡或事件捕获都有传播的特征
阻止事件传播的方法:
在W3C中使用 Event.stopPropagation();
在IE中使用 Event.cancelBubble=true;
var Event=ev||window.event;
if (Event.stopPropagation){
Event.stopPropagation();//非IE阻止事件传播
}else{
Event.cancelBubble=true;//IE阻止事件冒泡
}
四、阻止默认事件
var Event=ev||event;
if (Event.preventDefault) {
Event.preventDefault(); //非IE阻止默认事件
} else{
Event.returnValue=false; //IE阻止默认事件
};
return false; 代码中遇到立即停止执行,跳出正在执行的函数,相当于终止符,可以用来阻止默认事件
PS:注意使用位置,不能滥用
五、代码
组织事件传播示例:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>阻止事件传播</title> 6 <style> 7 *{margin:0;padding:0;list-style: none;} 8 ul{width:500px;height:300px;background: #ccc;} 9 li{width:300px;height:150px;background: pink;} 10 p{width:100px;height:100px;background:blue;} 11 </style> 12 </head> 13 <body> 14 <ul> 15 <li> 16 <p></p> 17 </li> 18 </ul> 19 <script> 20 var ul=document.getElementsByTagName('ul')[0]; 21 var li=document.getElementsByTagName('li')[0]; 22 var p=document.getElementsByTagName('p')[0]; 23 ul.onclick=function(){ 24 alert('我是ul'); 25 } 26 li.onclick=function(ev){ 27 alert('我是li'); 28 var e=window.event||ev; 29 if (e.stopPropagation) {//组织事件传播到父级 30 e.stopPropagation(); 31 //非IE阻止事件传播(W3C) 32 } else { 33 e.cancelBubble=true; 34 //IE阻止事件传播(IE) 35 } 36 } 37 p.onclick=function(){ 38 alert('我是p'); 39 } 40 41 </script> 42 </body> 43 </html>
自定义右击菜单练习:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin:0;padding:0;} 8 div{width:150px;height:300px;background: pink;display:none;position: absolute;} 9 span{color:red;} 10 </style> 11 </head> 12 <body> 13 <div> 14 <span>第一页</span> 15 <span>下一页</span> 16 <span>刷新</span> 17 </div> 18 <script> 19 var div=document.getElementsByTagName('div')[0]; 20 document.oncontextmenu=function(ev){//菜单右击事件 21 div.style.display='block'; 22 var e=window.event||ev; 23 if(e.preventDefault){//组织默认右击事件 24 e.preventDefault(); 25 }else{ 26 e.returnValue=false; 27 } 28 var winH=document.documentElement.clientHeight; 29 var winW=document.documentElement.clientWidth; 30 var divH=div.offsetHeight; 31 var divW=div.offsetWidth; 32 var x=e.clientX; 33 var y=e.clientY; 34 if (winH-y<divH) { 35 div.style.top=(y-divH)+'px'; 36 } else { 37 div.style.top=y+'px'; 38 } 39 if (winW-x<divW) { 40 div.style.left=(x-divW)+'px'; 41 } else { 42 div.style.left=x+'px'; 43 } 44 45 } 46 </script> 47 </body> 48 </html>