【兼容封装】addEventListener()和attachEvent()跨浏览器的兼容性处理
addEventListener()和attachEvent()相同點和不同點
相同點:
① 它們都是dom對象的方法,可以實現一種事件綁定多個事件處理函數;
② 相對于普通的DOM事件處理element.event = fun();的寫法來說,使用attachEvent和addEventListener時則可以實現多個事件處理函數的調用;
不同點:
① attachEvent是IE有的方法,它不遵循W3C標準,而其他的主流瀏覽器如FF等遵循W3C標準的瀏覽器都使用addEventListener,所以實際開發中需分開處理 — 涉及兼容;
② 多次綁定后執行的順序是不一樣的,attachEvent是后綁定先執行,addEventListener是先綁定先執行;
③ 綁定時間時,attachEvent必須帶on,如onclick,onmouseover等,而addEventListener不能帶on,如click,mouseover ;
④ attachEvent僅需要傳遞兩個參數,而addEventListener需要傳遞三個參數,這里牽扯到“事件流”的概念。偵聽器在偵聽時有三個階段:捕獲階段、目標階段和冒泡階段。順序為:捕獲階段(根節點到子節點檢查是否調用了監聽函數)→目 標階段(目標本身)→冒泡階段(目標本身到根節點)。此處的參數確定偵聽器是運行于捕獲階段、目標階段還是冒泡階段。 如果將 useCapture 設置為 true,則偵聽器只在捕獲階段處理事件,而不在目標或冒泡階段處理事件。 如果useCapture 為 false,則偵聽器只在目標或冒泡階段處理事件。 要在所有三個階段都偵聽事件,請調用兩次 addEventListener,一次將 useCapture 設置為 true,第二次再將useCapture 設置為 false;
關于 ④ 的理解可以轉至:點這里(講解一下這兩個參數順便補一下事件冒泡和事件捕獲的概念理解)
例子:
// 普通事件處理函數 --- 只執行最后一個事件綁定函數(只執行最后綁定的事件回調 >>> 3)btn.onclick = function(){alert(1);}btn.onclick = function(){alert(2);}btn.onclick = function(){alert(3);} // attachEvent事件處理函數調用 --- 后綁定先執行(IE8- >>> 3 2 1)btn1.attachEvent("onclick",function(){ alert(1); })btn1.attachEvent("onclick",function(){ alert(2); })btn1.attachEvent("onclick",function(){ alert(3); }) // addEventListener事件處理函數 --- 先綁定先執行(IE9+/主流瀏覽器 >>> 1 2 3)btn2.addEventListener("click",function(){ alert(1); },false)btn2.addEventListener("click",function(){ alert(2); },false)btn2.addEventListener("click",function(){ alert(3); },false)封裝 – 不同瀏覽器監聽事件和清除事件的方法
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title> </head> <body><button id="btn">點我</button> </body> <script type="text/javascript"> /**對監聽事件做兼容處理* 參數解釋:* element: 監聽事件源* type: 為監聽事件名,如click,submit等* handler: 為監聽事件所執行的函數* 調用: EventUtil.addHandler(添加事件)/removeHandler(移除事件)*/var EventUtil = {addHandler : function(type, handler, element){this.checked(type, handler, element);if(element.addEventListener){element.addEventListener(type, handler, false);}else if(element.attachEvent){element.attachEvent('on' + type, handler);}else{element['on' + type] = handler;}},removeHandler : function(type, handler, element){this.checked(type, handler, element);if(element.removeEventListener){element.removeEventListener(type, handler, false);}else if(element.detachEvent){element.detachEvent('on' + type, handler);}else{element['on' + type] = null;}},checked: function(type, handler, element){if(!(typeof(type) == 'string')) throw new Error("The parameter is required and the parameter type is String");if(!(handler instanceof Function)) throw new Error("The parameter is required and the parameter type is Function");return element = element ? element : document;}}var a = 111;var btn = document.getElementById('btn');var handler = function(){console.log('Hello World!');/* 移除事件 */// EventUtil.removeHandler(btn,'click',handler);}/* 添加事件 */EventUtil.addHandler('click', handler, btn); </script> </html>使用哈希值-表封裝
function addEvent(element, type, handler) {//為每一個事件處理函數分派一個唯一的IDif (!handler.$$guid) handler.$$guid = addEvent.guid++;//為元素的事件類型創建一個哈希表if (!element.events) element.events = {};//為每一個"元素/事件"對創建一個事件處理程序的哈希表var handlers = element.events[type];if (!handlers) {handlers = element.events[type] = {};//存儲存在的事件處理函數(如果有)if (element["on" + type]) {handlers[0] = element["on" + type];}}//將事件處理函數存入哈希表handlers[handler.$$guid] = handler;//指派一個全局的事件處理函數來做所有的工作element["on" + type] = handleEvent;};//用來創建唯一的ID的計數器addEvent.guid = 1;function removeEvent(element, type, handler) {//從哈希表中刪除事件處理函數if (element.events && element.events[type]) {delete element.events[type][handler.$$guid];}};function handleEvent(event) {var returnValue = true;//抓獲事件對象(IE使用全局事件對象)event = event || fixEvent(window.event);//取得事件處理函數的哈希表的引用var handlers = this.events[event.type];//執行每一個處理函數for (var i in handlers) {this.$$handleEvent = handlers[i];if (this.$$handleEvent(event) === false) {returnValue = false;}}return returnValue;};//為IE的事件對象添加一些“缺失的”函數 -- 冒泡兼容IE的處理function fixEvent(event) {//添加標準的W3C方法event.preventDefault = fixEvent.preventDefault;event.stopPropagation = fixEvent.stopPropagation;return event;};fixEvent.preventDefault = function () {this.returnValue = false;};fixEvent.stopPropagation = function () {this.cancelBubble = true;};總結
以上是生活随笔為你收集整理的【兼容封装】addEventListener()和attachEvent()跨浏览器的兼容性处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java随机数使用技巧(超简单)
- 下一篇: 2017年html5行业报告,云适配发布