摘自 js權(quán)威指南第三版
第一個要創(chuàng)建的方法是addHandler()续语,它的職責(zé)是視情況分別使用DOM0 級方法冒萄、DOM2 級方
法或IE 方法來添加事件充易。這個方法屬于一個名叫EventUtil 的對象菇民,本書將使用這個對象來處理瀏覽
器間的差異禁筏。addHandler()方法接受3 個參數(shù):要操作的元素持钉、事件名稱和事件處理程序函數(shù)。
與addHandler()對應(yīng)的方法是removeHandler()篱昔,它也接受相同的參數(shù)右钾。這個方法的職責(zé)是移
除之前添加的事件處理程序——無論該事件處理程序是采取什么方式添加到元素中的,如果其他方法無
效,默認(rèn)采用DOM0 級方法舀射。
var EventUtil = {
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: 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;
}
}
};
這兩個方法首先都會檢測傳入的元素中是否存在DOM2 級方法窘茁。如果存在DOM2 級方法,則使用
該方法:傳入事件類型脆烟、事件處理程序函數(shù)和第三個參數(shù)false(表示冒泡階段)。如果存在的是IE 的
方法邢羔,則采取第二種方案驼抹。注意拜鹤,為了在IE8 及更早版本中運(yùn)行,此時的事件類型必須加上"on"前綴敏簿。
最后一種可能就是使用DOM0 級方法(在現(xiàn)代瀏覽器中,應(yīng)該不會執(zhí)行這里的代碼)惯裕。此時,我們使用
的是方括號語法來將屬性名指定為事件處理程序蜻势,或者將屬性設(shè)置為null撑刺。
可以像下面這樣使用EventUtil 對象:
var btn = document.getElementById("myBtn");
var handler = function() {
alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
//這里省略了其他代碼
EventUtil.removeHandler(btn, "click", handler);
var EventUtil = {
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
getEvent: function(event) {
return event ? event: window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: 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;
}
},
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
以上代碼顯示够傍,我們?yōu)镋ventUtil 添加了4 個新方法。第一個是getEvent()挠铲,它返回對event
對象的引用王带。考慮到IE 中事件對象的位置不同市殷,可以使用這個方法來取得event 對象愕撰,而不必?fù)?dān)心指
定事件處理程序的方式。在使用這個方法時醋寝,必須假設(shè)有一個事件對象傳入到事件處理程序中搞挣,而且要
把該變量傳給這個方法,如下所示音羞。
btn.onclick = function(event) {
event = EventUtil.getEvent(event);
};
在兼容DOM 的瀏覽器中囱桨,event 變量只是簡單地傳入和返回。而在IE 中嗅绰,event 參數(shù)是未定義
的(undefined)舍肠,因此就會返回window.event搀继。將這一行代碼添加到事件處理程序的開頭,就可以確
保隨時都能使用event 對象翠语,而不必?fù)?dān)心用戶使用的是什么瀏覽器叽躯。
第二個方法是getTarget(),它返回事件的目標(biāo)肌括。在這個方法內(nèi)部点骑,會檢測event 對象的target
屬性,如果存在則返回該屬性的值谍夭;否則黑滴,返回srcElement 屬性的值〗羲鳎可以像下面這樣使用這個方法袁辈。
btn.onclick = function(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
};
第三個方法是preventDefault(),用于取消事件的默認(rèn)行為珠漂。在傳入event 對象后晚缩,這個方法
會檢查是否存在preventDefault()方法,如果存在則調(diào)用該方法甘磨。如果preventDefault()方法不
存在,則將returnValue 設(shè)置為false眯停。下面是使用這個方法的例子济舆。
var link = document.getElementById("myLink");
link.onclick = function(event) {
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
};
以上代碼可以確保在所有瀏覽器中單擊該鏈接都不會打開另一個頁面。首先莺债,使用EventUtil.
getEvent()取得event 對象滋觉,然后將其傳入到EventUtil.preventDefault()以取消默認(rèn)行為。
第四個方法是stopPropagation()齐邦,其實(shí)現(xiàn)方式類似椎侠。首先嘗試使用DOM 方法阻止事件流,否
則就使用cancelBubble 屬性措拇。下面看一個例子我纪。
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
alert("Clicked");
event = EventUtil.getEvent(event);
EventUtil.stopPropagation(event);
};
document.body.onclick = function(event) {
alert("Body clicked");
};
在此,首先使用EventUtil.getEvent()取得了event 對象丐吓,然后又將其傳入到EventUtil.
stopPropagation()浅悉。別忘了由于IE 不支持事件捕獲券犁,因此這個方法在跨瀏覽器的情況下,也只能用
來阻止事件冒泡粘衬。