javascript事件处理解析
一、什么是事件!(w3c解释)
事件是可以被 JavaScript 侦测到的行为。
JavaScript 使我们有能力创建动态页面。事件是可以被 JavaScript 侦测到的行为。
网页中的每个元素都可以产生某些可以触发 JavaScript 函数的事件。比方说,我们可以在用户点击某按钮时产生一个 onClick 事件来触发某个函数。事件在 HTML 页面中定义。
二、事件的级别
在工作中我们书写js代码的时候的会有两种书写js的习惯;如下所示:
//第一种书写方式 var btn3 = document.getElementById("btn3"); btn3.onclick = function(){ /*这里执行相应的代码*/ }; //这种书写方式是dom0级事件书写的方式 //第二种书写方式 var btn3 = document.getElementById("btn3"); btn3.addEventListener('click',function(){ /*这里执行相应的代码*/ },false); //这种是dom2级事件处理方式
在dom2级事件处理函数中定义了两个用来添加和删除事件的处理函数:
addEventListener('事件',函数,是否冒泡标志);
removeEventListener('事件',函数,是否冒泡标志);
参数说明:'事件'如单击事件'click',"函数"指的是事件发生后需要处理的动作,可以直接调用函数名,也可以直接在这里写代码,'是否冒泡标志',设置false冒泡,设置true为捕获。
添加事件和删除事件的参数值是完全相同的。
注明:使用addEventListener添加的函数只能通过removeEventListener删除,设置null不起作用,而且删除事件的参数要和添加事件的参数要完全相同才可以删除!
//第一种
var btn3 = document.getElementById("btn3"); btn3.addEventListener('click',function(){ alert('按钮'); },false);
btn3.removeEventListener('click',function(){ alert('按钮'); },false);
//第二种
btn3.addEventListener('click',showMess,false);
btn3.removeEventListener('click',showMess,false);
function showMess(){
alert('按钮');
}
dom2级事件处理函数在IE下是不支持的,IE有自己的dom2级事件处理函数:
如下:
attachEvent('onclick',showMess);//IE下面添加事件
detachEvent('onclick',showMess);//IE下删除事件
IE下面的这两个事件处理函数的参数也是完全一致的!
IE下没有事件的冒泡的标志,因为IE默认就是以冒泡的形式来处理事件的!
三、事件的冒泡和捕获
1、事件流的定义
DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有着相当大的影响。这两种事件流分别是捕获和冒泡。和许多Web技术一 样,在它们成为标准之前,Netscape和微软各自不同地实现了它们。Netscape选择实现了捕获事件流,微软则实现了冒泡事件流。幸运的 是,W3C决定组合使用这两种方法,并且大多数新浏览器都遵循这两种事件流方式。
2、什么是事件冒泡流
当事件在某一DOM元素被触发时,例如用户在客户名字节点上点击鼠标,事件将跟随着该节点继承自的各个父节点冒泡穿过整个的DOM节点层次,直到它遇到依 附有该事件类型处理器的节点,此时,该事件是onclick事件。在冒泡过程中的任何时候都可以终止事件的冒泡,在遵从W3C标准的浏览器里可以通过调用 事件对象上的stopPropagation()方法,在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播,事件将一直通过DOM冒泡直至到达文档根。
3、什么是事件捕获流
事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事 件目标元素之间各个继承派生的元素所捕获,如果事件监听器在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何元素以 对事件做出处理;否则,事件会被接着传递给派生元素路径上的下一元素,直至目标元素。事件到达目标元素后,它会接着通过DOM节点再进行冒泡。
4、不同浏览器处理下的冒泡和捕获在非IE浏览器下,阻止事件的冒泡是通过函数stopPropagation();来阻止的。而在IE下是通过设置变量cancelBubble = true;来阻止事件的冒泡,这是IE特有的变量。
使用如下:
function stopPropagation(event){ if(event.stopPropagation) { event.stopPropagation();//非IE } else { event.cancelBubble = true;//IE } }
一般情况下处理事件的都是按照冒泡来处理的,所以针对事件捕获的处理只有在特殊情况下才用得到!
四、事件的默认行为
事件的默认的行为就是标签在设计之时给予的行为,比如a标签的默认行为就是跳转页面,提交按钮的默认行为就是提交表单!有时候我们不希望标签在特定的环境下执行他们的默认的行为,这个就要用程序来阻止事件的默认的行为!当然阻止事件默认的行为的通用方法就是设置return false;但是这种方法比较危险,可能导致后续所有的程序不能执行,所以在一般情况下,我们采用浏览器默认的方法来阻止事件的默认行为。
在非IE下阻止事件的默认行为是通过函数preventDefault();来阻止的。
在IE下是通过设置变量returnValue = false;来阻止的。
使用如下:
function preventDefault(event) { if(event.preventDefault) { event.preventDefault();//非IE } else { event.returnValue = false;//IE }
}
五、事件封装
var eventMy={ // 添加事件 addE:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent('on'+type,handler); }else{
//在js中中括号等价于"." element['on'+type]=handler; } }, // 删除事件 removeE:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type]=null; } }, getE:function(event){//获取事件对象
/*
事件enent在非IE和IE8以后的浏览器可以直接获取,
而在IE8之前的浏览器要通过window.event来获取
*/ return event?event:window.event; }, getEType:function(event){ return event.type;//获取事件的类型如'click' }, getETarget:function(event){
//获取事件的目标在非IE下用e.target,在ie下用e.srcElement return event.target || event.srcElement; }, preventDefault:function(event){ if(event.preventDefault){ event.preventDefault();//阻止事件的默认行为(非IE) }else{ event.returnValue=false;//阻止事件的默认行为(IE) } }, stopPropagation:function(event){ if(event.stopPropagation){
//阻止事件的冒泡(非IE) event.stopPropagation(); }else{
//阻止事件的冒泡(IE) event.cancelBubble=true; } } }
使用方法如下:
window.onload=function(){ var go=document.getElementById('go'), box=document.getElementById('box'); eventMy.addE(box,'click',function(){ alert('11'); }); eventMy.addE(go,'click',function(e){ e=e || window.event;//这里为了方便就不直接调用封装的代码来获取 alert(eventMy.getETarget(e).nodeName);//e.target.nodeName获取事件的事件载体的节点名称 eventMy.preventDefault(e); eventMy.stopPropagation(e); }); }