

js中事件监听就是利用addEventListener来绑定一个事件,这个用法在jquery中非常常用并且简单,但在原生js中比较复杂,这里整理了addEventListener事件各方法的测试与例子供大家参考学习。
在前两天做播放器的时候添加监听后删除监听遇到了一点麻烦,删不掉,后来看了一下才发现,参数需要完全对应,什么叫完全对应呢,换句话说:
 代码如下:$('.video')[0].addEventListener('timeupdate', currentTimeHandler, true);
比如这句,需要传入三个参数,这样才能够删除,为什么一定要这样,没错,蛋疼的地方就在这里:
在add和remove时,第三个参数确实可以不写,但此时他们的默认情况是不一样的!!
通常情况下addEventListener是false…
1、 添加自定义事件监听
 代码如下:var eventHandlesCounter=1;//统计添加事件监听的个数,0作为预留位
 function addEvent(obj,evt,fn){
 if(!fn.__EventID){ fn.__EventID=eventHandlesCounter++;}
 if(!obj.__EventHandles){ obj.__EventHandles=[]; }
 if(!obj.__EventHandles[evt]){
 obj.__EventHandles[evt]=[];
 if(obj["on"+evt] instanceof Function){
 obj.__EventHandles[evt][0]=obj["on"+evt];
 obj["on"+evt]=handleEvents;
 }
 }
 obj.__EventHandles[evt][fn.__EventID]=fn;
 
 function handleEvents(){
 var fns = obj.__EventHandles[evt];
 for (var i=0;i
 }
}
2、自定义删除事件监听
 代码如下:function delEvent(obj,evt,fn){
 if(!obj.__EventHandles || !obj.__EventHandles[evt] || !fn.__EventID){
 return false;
 }
 if(obj.__EventHandles[evt][fn.__EventID]==fn){
 delete obj.__EventHandles[evt][fn.__EventID];
 }
}
3. 对上述方法进行修正
 代码如下:function addEvent(obj,evt,fn,useCapture){
 if(obj.addEventListener){//优先使用W3C事件注册
 obj.addEventListener(evt,fn,!!useCapture);
 }else{
 if(!fn.__EventID){fn.__EventID = addEvent.__EventHandlesCounter++;}
 if(!obj.__EventHandles){ obj.__EventHandles=[];}
 if(!obj.__EventHandles[evt]){
 obj.__EventHandles[evt]=[];
 if(obj["on"+evt]){
 (obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;
 }
 obj["on"+evtype]=addEvent.execEventHandles;
 }
 }
}
addEvent.__EventHandlesCounter=1;
addEvent.execEventHandles = function(evt){
 if(!this.__EventHandles) {return true;}
 evt = evt || window.event;
 var fns = this.__EventHandles[evt.type];
 for (var i=0;i
 fns[i].call(this);
 }
 }
};
function delEvent(obj,evt,fn,useCapture){
 if (obj.removeEventListener) {//先使用W3C的方法移除事件处理函数 
 obj.removeEventListener(evt,fn,!!useCapture);
 }else {
 if(obj.__EventHandles){
 var fns = obj.__EventHandles[evt];
 if(fns){delete fns[fn.__EventID];}
 }
}
4、标准化事件对象
 代码如下:function fixEvent(evt){
 if(!evt.target){
 evt.target = evt.srcElement;
 evt.preventDefault=fixEvent.preventDefault;
 evt.stopPropagation = fixEvent.stopPropagation;
 if(evt.type == "mouseover"){
 evt.relatedTarget = evt.fromElement;
 }else if(evt.type == "mouseout"){
 evt.relatedTarget = evt.toElement;
 }
 evt.charCode =(evt.type == "keypress")?evt.keyCode:0;
 evt.eventPhase = 2;
 evt.timeStamp = (new Date()).getTime();
 }
return evt;
}
fixEvent.preventDefault=function(){ this.returnValue=false;}
fixEvent.stopPropagation=function(){this.cancelBubble = true;};
fixEvent函数不是单独执行的,它必须有一个事件对象参数,而且只有事件发生时它才被执行!最好的方法是把它整合到addEvent函数的execEventHandles里面。
 代码如下:addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
if (!this.__EventHandles) {return true;}
evt = fixEvent(evt || window.event);//在这里对其进行标准化操作
var fns = this.__EventHandles[evt.type];
for (var i=0;i< fns.length;i++) {
if (fns[i] instanceof Function) {
fns[i].call(this,evt);//并且将其作为事件处理函数的第一个参数
//这样在事件处理函数内部就可以使用统一的方法访问事件对象了 } } };
上面是高手写了,下面整理几个实际的监听事情的例子
 代码如下:
 
1. IE使用attachEvent/detachEvent方法来添加和删除事件;w3c使用addEventListener/removeEventListener方法。
2. IE对其事件使用onevent的命名方式,而w3c的是event的命名方式。
3. IE事件内使用的是一个全局的Event对象,而w3c是将event对象作为参数传递给。
4. 为了避免触发默认的事件行为,IE的做法是要求程序员设置Event对象中的returnValue属性值为false,而w3c的做法是执行preventDefault方法。
5. IE没有提供对事件捕获阶段的支持。
6. 要停止事件的传递,IE的做法是设置event对象的cancelBubble为true,而w3c的做法是设置执行stopPropagation方法。
7. IE将事件当做一个的函数来调用,而w3c中它是作为对象的方法来调用的,这表示在ie中事件中的this关键字指向的不是事件发生对象而是一个没用的全局对象(window对象)。
8. IE在使用事件方面存在内存泄露问题。在IE浏览器中,如果要为某个元素创建一个事件,并且在中使用该元素,则在用户进入其他页面之前,该以及相关的DOM节点作占据的内存空间不会被释放。
希望本文所述对大家的javascript程序设计有所帮助。
