一、為什么需要事件監聽?
我們可不可以為同一對象的同一事件綁定多個事件處理程序呢?
通過行內綁定和動態綁定是不可以的,但是可以通過事件監聽來實現。
window.onload = function() {
// 動態綁定
document.getElementById('btn').onclick = function() {
alert('first');
}
// 動態綁定
document.getElementById('btn').onclick = function() {
alert('second');
}
}
<input type="button" value="點擊" id="btn">
二、如何實現事件監聽?
由於Javascript屬於客戶端語言,又由於所有瀏覽器並不是同一廠家生產的,沒有統一的標准,所以Javascript具有兼容性問題,同理,事件監聽也具有兼容性問題,在不同瀏覽器下創建的方式也是不同的。
1. 基於IE內核的瀏覽器(IE8以下版本、360、搜狗、2345瀏覽器的兼容模式)
DOM對象.attachEvent(type,callback);
主要功能:為某個DOM對象的某個type事件綁定相關的事件處理程序(callback)
| 參數 | 說明 |
| type | 事件類型,如onclick,onkeydown |
| callback | 事件的處理程序,通常是一個匿名函數 |
window.onload = function() {
// 在IE瀏覽器下使用事件監聽
document.getElementById('btn').attachEvent('onclick',function(){
alert('first');
})
// 在IE瀏覽器下使用事件監聽
document.getElementById('btn').attachEvent('onclick',function(){
alert('second');
})
}
2. 基於W3C內核的瀏覽器(IE9以上版本、火狐瀏覽器、谷歌瀏覽器、國內瀏覽器的極速模式)
DOM對象.addEventListener(type,callback,capture);
主要功能:為某個DOM對象的某個type事件綁定相關的事件處理程序(callback)
| 參數 | 說明 |
| type | 事件類型,不帶on前綴,如click、keydown |
| callback | 事件的處理程序,通常是一個匿名函數 |
| capture | 瀏覽器模型,true(捕獲模型),false(冒泡模型),默認IE8以下瀏覽器只支持冒泡模型,所以其值默認為false。 |
window.onload = function() {
// 在W3C瀏覽器下使用事件監聽
document.getElementById('btn').addEventListener('click',function(){
alert('first');
})
// 在W3C瀏覽器下使用事件監聽
document.getElementById('btn').addEventListener('click',function(){
alert('second');
})
}
三、IE內核與W3C內核事件監聽區別
1. 綁定語法不同
IE:attachEvent
W3C:addEventListener
2. type參數不同
IE:事件需要添加'on'前綴,如on+事件
W3C:事件不需要添加'on'前綴,如事件
3. 參數數量不同
IE:2個參數,type、callback
W3C:3個參數,type、callback、capture(瀏覽器模型)
4. 觸發順序不同
IE:倒序觸發,先綁定后觸發
W3C:正序觸發,先綁定先觸發
四、解決事件監聽的兼容性
/**
* 解決事件監聽兼容性問題
* @param {Object} obj對象
* @param {String} type時間類型,不帶'on'前綴
* @param {Function} callback事件處理程序
*/
function addEvent(obj,type,callback) {
if (obj.addEventListener) {
// W3C內核
obj.addEventListener(type,callback);
} else {
// IE內核
obj.attachEvent('on'+type,callback);
}
}
window.onload = function() {
// 為btn按鈕綁定事件監聽
addEvent(document.getElementById('btn'),'click',function(){
alert('first');
})
// 為btn按鈕綁定事件監聽
addEvent(document.getElementById('btn'),'click',function(){
alert('second');
})
}
五、移除事件監聽
在實際項目開發中,可能需要動態移除事件監聽程序。
1. 基於IE內核瀏覽器
detachEvent(type,callback); // 移除事件監聽
主要功能:在IE內核瀏覽器下移除事件監聽程序
| 參數 | 說明 |
| type | 要移除的事件類型,如onclick、onmouseover |
| callback | 要移除事件處理程序的名稱,通常是函數名稱 |
2. 基於W3C內核瀏覽器
removeEventListener(type,callback); // 移除事件監聽
主要功能:在W3C內核瀏覽器下移除事件監聽程序
| 參數 | 說明 |
| type | 要移除的事件類型,如click、mouseover |
| callback | 要移除事件處理程序的名稱,通常是函數名稱 |
特別說明:如果一個對象向進行事件移除,那么其綁定事件監聽時事件處理程序必須是有名函數,否則是無法進行移除的,謹記!!!
function fn1() {
alert('first');
}
function fn2() {
alert('second');
}
window.onload = function() {
var btn = document.getElementById('btn');
var del = document.getElementById('del');
// 為btn按鈕綁定事件監聽
addEvent(btn,'click',fn1);
// 為btn按鈕綁定事件監聽
addEvent(btn,'click',fn2);
del.onclick = function() {
// IE內核下移除fn1事件監聽程序
btn.detachEvent('onclick',fn1);
// W3C內核下移除fn2事件監聽程序
btn.removeEventListener('click',fn2);
}
}
<input type="button" value="點擊" id="btn"> <input type="button" value="移除" id="del">
六、解決移除事件監聽的兼容性問題
/**
* 解決移除事件監聽兼容性問題
* @param {Object} obj對象
* @param {String} type時間類型,不帶'on'前綴
* @param {Function} callback事件處理程序
*/
function removeEvent(obj,type,callback) {
if (obj.removeEventListener) {
// W3C內核
obj.removeEventListener(type,callback);
} else {
// IE內核
obj.detachEvent('on'+type,callback);
}
}
function fn1() {
alert('first');
}
function fn2() {
alert('second');
}
window.onload = function() {
var btn = document.getElementById('btn');
var del = document.getElementById('del');
// 為btn按鈕綁定事件監聽
addEvent(btn,'click',fn1);
// 為btn按鈕綁定事件監聽
addEvent(btn,'click',fn2);
del.onclick = function() {
// 兼容性移除
removeEvent(btn,'click',fn1);
removeEvent(btn,'click',fn2);
}
}

