不同瀏覽器對事件模型的支持歷經三個階段:DOM0 級(onclick)、DOM2 級(addEventListener)、IE 專有(attachEvent)。為了統一接口,通常封裝一個 EventUtil 對象。
var EventUtil = {
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false); // 冒泡階段
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler); // IE 需加 "on" 前綴
} else {
element["on" + type] = handler; // DOM0 級降級
}
},
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;
}
}
};
var btn = document.getElementById("myBtn");
var handler = function() { alert("clicked"); };
EventUtil.addHandler(btn, "click", handler);
// 移除時:EventUtil.removeHandler(btn, "click", handler);
addEventListener,其次 IE attachEvent,最後降級 DOM0 級。這保證了現代瀏覽器走標準路徑。attachEvent 要求事件類型帶 "on" 前綴(如 "onclick"),而標準 API 不帶。addEventListener 的第三個參數 false 表示冒泡階段捕獲,true 為捕獲階段。此處統一用冒泡。handler 變量。現代瀏覽器(IE9+)均支持 addEventListener/removeEventListener,若不需兼容 IE8 及以下,可直接使用原生 API。此外,handleEvent 方法與 {once: true} 選項提供更強大的控制。
EventUtil 是前端早期跨瀏覽器兼容的經典封裝,展示了能力檢測而非瀏覽器檢測的最佳實踐。雖然現代項目較少直接使用,但理解其原理有助於掌握事件模型演進歷程。