DOM 中的事件處理介紹

來源:互聯網
上載者:User

該介面提供了 'addEventListener' 和 'removeEventListener' 方法,用來綁定或解除綁定一個 EventListeners 介面到一個 EventTarget。

DOM 2 Events 中定義了 Event 介面,用來提供事件的上下文資訊,它提供了若干標準屬性和方法。 實現 Event 介面的對象一般作為第一個參數傳入事件處理函數,以用來提供當前事件相關的一些資訊。

事件註冊
根據 DOM 2 Events 中描述,節點使用 'addEventListener' 和 'removeEventListener' 方法綁定和解除綁定事件監聽器,但 IE6 IE7 IE8 不支援這兩個方法, 而使用 'attachEvent' 和 'detachEvent' 方法作為替代方案,Opera 兩類方法都支援。Chrome Safari Firefox 只支援標準方法。

為瞭解決瀏覽器安全色問題,可以自訂函數來解決。例如:
複製代碼 代碼如下:
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;
}
}
};


關於 'addEventListener' 和 'attachEvent' 有幾點需要注意:

IE 不支援在捕獲階段觸發事件監聽器,'attachEvent' 方法沒有提供參數說明是否響應在捕獲階段觸發的事件;
'addEventListener' 和 'attachEvent' 都可以註冊多個事件監聽器;
在 Firefox Chrome Safari Opera 中給同一事件註冊同一個事件監聽器多次,重複註冊的會被丟棄;而在 IE 中重複註冊的事件監聽器會被重複執行多次;
當給同一元素註冊了多個事件監聽器的時候,IE6 IE7 的事件監聽器執行順序是隨機的,IE8 是倒序的,Firefox Chrome Safari Opera 是順序的;
當元素註冊的事件監聽器中有非法的事件監聽器時(非函數),在 IE Firefox 中會拋出異常,而在 Chrome Safari Opera 中則會忽略非法的事件監聽器,繼續執行其他的事件監聽器。
事件對象
在ie中,事件對象是作為一個全域變數來儲存和維護的。 所有的瀏覽器事件,不管是使用者觸發的,還是其他事件, 都會更新window.event 對象。 所以在代碼中,只要輕鬆調用 window.event 就可以輕鬆擷取 事件對象, 再 event.srcElement 就可以取得觸發事件的元素進行進一步處理。

對於標準的 DOM 處理來說, 事件對象卻不是全域對象,一般情況下,是現場發生,現場使用,把事件對象自動傳遞給對應的事件處理函數。 在代碼中,函數的第一個參數就是事件對象了。

為瞭解決相容性問題,通常在代碼中如下處理:
複製代碼 代碼如下:
function handler(e){
e = e || window.event;
}

需要注意的是,使用 <button id="btn" onclick="foo()">按鈕1</button> 進行事件註冊,標準方式下卻不能在事件處理方法中取得事件對象。

原因是 onclick="foo()" 就是直接執行了, foo() 函數,沒有任何參數傳遞給 foo 函數。

有兩個辦法解決這個問題。

第一,將註冊的方法修改為 <button id="btn" onclick="foo(event)">按鈕</button>,注意,這裡的 event 不是形參,而是實參,必須名為 event。這樣 foo 函數就可以得到事件參數了。

第二,不修改註冊的代碼,在事件處理方法上進行處理。關鍵在於此時實際上存在事件對象,只不過沒有傳遞給 foo 函數罷了,我們可以找到調用 foo 函數的那個函數,當然這是一個系統函數,沒有關係,通過 foo.caller 可以取得當前調用 foo 函數的函數,這個函數的第一個參數就是事件對象,所以,我們可以這樣取得這個事件對象了。foo.caller.arguments[0]。

注意:

只有在使用 attachEvent 方法註冊事件監聽器的時候,IE 才支援使用事件監聽器傳入的第一個參數作為事件對象的方式;
Chrome Safari Opera 兩種擷取事件對象的方式都支援;
Firefox 只支援擷取事件對象的標準方式。
事件對象的屬性
IE 對事件對象的標準屬性和方法支援有限,針對大部分屬性和方法,IE 都提供了一套替代非標準的替代方案; 而 Firefox Chrome Safari Opera 除了全面支援事件對象的標準屬性和方法外,還在不同程度上支援了 IE 提供的非標準替代方案。

使用特性判斷使用與標準對應的非標準方法及屬性

  target          srcElement

  preventDefault()     returnValue

  stopPropagation()    cancelBubble

  relatedTarget      fromElement toElement

例如:
複製代碼 代碼如下:
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;
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}


參考資料:

SD9011: 事件模型在各瀏覽器中存在差異

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.