本文實例講述了Javascript添加監聽與刪除監聽的用法。分享給大家供大家參考。具體分析如下:
js中事件監聽就是利用addEventListener來綁定一個事件,這個用法在jquery中非常常用且簡單,但在原生js中比較複雜,這裡整理了addEventListener事件各方法的測試與範例供大家參考學習。
在前兩天做播放器的時候添加監聽後刪除監聽遇到了一點麻煩,刪不掉,後來看了一下才發現,參數需要完全對應,什麼叫完全對應呢,換句話說:
$('.video')[0].addEventListener('timeupdate', currentHandler , 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
fns[i].call(this);
}
}
2、自訂刪除事件監聽
function delfn(obj,evt,fnfn(obj,evt,){
if(!obj.__EventHandles || !obj.__EventHandles[evt] || !fn.__EventID){
return false;
}
if(obj.__EventHandles[evt][fn.__EventID]==fn){
delete obj.__EventHandles[evt][fn.__EventID];
}
}
3. 修正上述方法
函數addEvent(obj,evt,fn,useCapture){
if(obj.addEventListener){//優先使用W3C事件註冊
obj.addEventListener(evt,fn,!!useCapture);
}其他{
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;}
事件=事件|| window.event;
var fns = this.__EventHandles[evt.type];
for (var i=0;i
if(fns[i] instanceof 函數){
fns[i].call(this);
}
}
};
函數 delEvent(obj,evt,fn,useCapture){
if (obj.removeEventListener) {//先使用W3C的方法刪除事件處理函數
obj.removeEventListener(evt,fn,!!useCapture);
}否則{
if(obj.__EventHandles){
var fns = obj.__EventHandles[evt];
if(fns){刪除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 == "滑鼠懸停"){
evt.latedTarget = 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();
}
返回事件;
}
fixEvent.preventDefault=function(){ this.returnValue=false;}
fixEvent.stopPropagation=function(){this.cancelBubble = true;};
fixEvent函數不是單獨執行的,它必須有一個事件物件參數,而且只有事件發生時它才會執行!
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
if (fns[i] instanceof 函數) {
fns[i].call(this,evt);//並且將作為其事件處理函數的第一個參數
//這樣在事件處理函數內部就可以使用統一的方法存取事件物件了 } } };
上面是高手寫的,下面整理了幾個實際的監聽事情的例子
複製程式碼 如下程式碼:
test6.html
這裡使用document.getElementById("1").attachEvent("onclick",test);進行動態的事件綁定,使用
複製程式碼
代碼如下:
複製程式碼
程式碼如下:
test7.html
請輸入數字
這裡的event是一個事件對象,他能回傳很多的信息,具體請參考相關文檔。
補充:事件監聽方面的相容
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程式設計有所幫助。