DOM事件之事件冒泡
什么是事件流?
事件流----描述的是从页面中接受事件的顺序。
IE浏览器的是事件冒泡流
什么是事件冒泡呢?
事件冒泡:指事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档)。
例如:
<div id="box"> <input type="button" value="按钮" id="btn"/> </div>
当点击了该按钮的时候,浏览器会默认为点击了该按钮的同时也会触发包含该按钮的容器div,当点击div时会触发body,当点击body时会触发整个html,之后再进行点击HTML会触发整个document。
事件冒泡兼容各种浏览器。
什么是事件捕获呢?
事件捕获与事件冒泡刚好相反,事件捕获:指不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。就以上面的为例子:触发的顺序为:document->html->body->div->input
事件捕获比较支持的是老版本的浏览器。
事件处理程序
1、Html事件处理程序
直接将事件写入HTML结构中:
例如:
效果图:
<div id="box"> <input type="button" value="按钮" id="btn" onclick="alert('欢迎来到perfect*博客园')"/> </div>
该代码等同于:
<div id="box"> <input type="button" value="按钮" id="btn" onclick="show()"/> </div> <script> function show(){ alert('欢迎来到perfect*博客园'); } </script>
HTML事件的缺点:
html和JS代码紧密的耦合在一起:当修改了JS的代码,也需要进行修改HTML结构中相关的代码,比较麻烦。
2、DOM0级事件处理程序
较传统的方式:把一个函数赋值给一个事件的处理程序属性,该事件处理程序用的比较多的方法。
优点:
1、简单
2、跨浏览器的优势
1 <div id="box"> 2 <input type="button" value="按钮" id="btn" onclick="show()"/> 3 <input type="button" value="按钮2" id="btn2" /> 4 </div> 5 <script> 6 function show(){ 7 8 alert('欢迎来到perfect*博客园'); 9 } 10 11 var btn2=document.getElementById('btn2'); 12 btn2.onclick=function(){ 13 14 alert("这是通过Dom0级添加的事件!!"); 15 } 16 </script>
当点击按钮2的效果:
不存在HTML事件处理程序的缺点。
btn2.onclick=null;//删除onclick事件
3、DOM2级事件处理程序
DOM2级事件定义了两个方法:
用于处理指定和删除事件处理程序的操作addEventListener()和removeEvenListener().
接收三个参数:要处理的事件名,作为事件处理程序的事件函数和布尔值;这里的布尔值为true时表示在捕获阶段进行调用事件捕获程序,而false则为在冒泡阶段调用事件冒泡程序。
例如:
实现的效果:
通过addEventListener()添加的事件只能通过removeEventListener()进行删除事件,两者是配对使用的,添加了什么参数就删除什么参数。
总的demo:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>事件的冒泡</title> 6 7 </head> 8 <body> 9 <div id="box"> 10 <input type="button" value="按钮" id="btn" onclick="show()"/> 11 <input type="button" value="按钮2" id="btn2" /> 12 <input type="button" value="按钮3" id="btn3" /> 13 </div> 14 <script> 15 function show(){ 16 17 alert('欢迎来到perfect*博客园'); 18 } 19 function show1(){ 20 21 alert('欢迎来到perfect*博客园1'); 22 } 23 24 var btn2=document.getElementById('btn2'); 25 var btn3=document.getElementById("btn3"); 26 27 btn2.onclick=function(){ 28 29 alert("这是通过Dom0级添加的事件!!"); 30 } 31 btn2.onclick=null; 32 33 //Dom2级事件处理程序 34 btn3.addEventListener("click",show1,false); 35 //删除事件 36 btn3.removeEventListener("click",show1,false); 37 38 39 </script> 40 </body> 41 </html>
还有一种写法:使用this:表示这个事件在哪里出发的这个this就会引用它
效果图:
从以上可以说明在一个按钮上可以添加多个事件处理程序,进行按顺序进行执行
4、IE事件处理程序
attachEvent()添加事件
detachEvent()删除事件
接收相同的两个参数:事件处理的名称和事件处理程序的函数;
不使用第三个参数的原因:IE8以及更早的浏览器版本只支持事件的冒泡;
支持IE事件处理程序的浏览器:IE和opera
综上出现的问题:当使用事件Dom2事件处理程序时,IE浏览器不支持,当使用IE事件处理程序时,其它的浏览器不支持,因此引入下面所要说的跨浏览器的事件处理程序。
5、跨浏览器的事件处理程序
建议封装在一个对象类:
var btn3=document.getElementById("btn3"); function show123(){ alert('欢迎来到perfect*博客园123'); } //跨浏览器事件处理程序 var eventUtil={ //添加句柄 //触发的对象,触发的事件类型,触发的操作 addHandler:function(element,type,handler){ //Dom2级事件处理程序的判断 if(element.addEventListener){ element.addEventListener(type,handler,false); //IE事件处理程序的判断 }else if(element.attachEvent){ element.attachEvent('on'+type,handler); //DOM0级事件处理程序的判断 }else{ element['on'+type]=handler; } }, //删除句柄 //触发的对象,触发的事件类型,触发的操作 removeHandler:function(element,type,handler){ //Dom2级事件处理程序的判断 if(element.removeEventListener){ element.removeEventListener(type,handler,false); //IE事件处理程序的判断 }else if(element.detachEvent){ element.detachEvent('on'+type,handler); //DOM0级事件处理程序的判断 }else{ element['on'+type]=null; } }, } eventUtil.addHandler(btn3,"click",show123);
删除添加的事件:
加入该段代码即可
eventUtil.removeHandler(btn3,"click",show123);