〈基本事件模型〉的缺點之一,就是只能註冊一個事件處理器,如果你想註冊多個事件處理器,那麼類似以下的方式是行不通的:
window.onload = function() {
// 處理器一
};
window.onload = function() {
// 處理器二
};
在上例中,第二個函式實例會成為 onload
參考的對象,而第一個函式實例就不再有用了。
如果想在基本事件處理中,在事件發生時處理時呼叫兩個以上的函式,必須透過設計的方式來達到,最簡單的方式之一就是…
function handler1() {
}
function handler2() {
}
window.onload = function() {
handler1();
handler2();
};
但通常這類設計方式不好管理。事件模型在 DOM Level 2 時獲得標準化,又稱為標準事件模型,DOM Level 2 事件模型允許一次註冊兩個以上的事件,在 Internet Explorer 9 之後,DOM Level 2 事件模型也得到比較好的支援了。
在 DOM Level 2 事件模型中,要註冊事件,必須使用 addEventListener
方法。舉個例子來說,若要以 DOM Level 2 事件模型實現〈基本事件模型〉中第一個範例,可以如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<button id="btn1">按鈕一</button><br>
<button id="btn2">按鈕二</button><br>
<div id="console"></div>
<script type="text/javascript">
function handler() {
document.getElementById('console').innerHTML
= `Who's clicked: ${this.id}`;
}
document.getElementById('btn1')
.addEventListener('click', handler, false);
document.getElementById('btn2')
.addEventListener('click', handler, false);
</script>
</body>
</html>
addEventListener
的第一個參數指出要註冊的事件,不需要 'on'
開頭,第二個參數是事件處理器,第三個參數為 false
時,表示這是個事件浮昇處理器(之後文件會再說明)。
在上例中,於事件處理器中使用 this
取得目前觸發事件的元素,雖然目前多數遵守 DOM Level 2 的瀏覽器都會如此實作,不過這並不是 DOM Level 2 標準的規範,在 DOM Level 2 的標準中,可以從 Event
實例的 currentTarget
特性來取得目前觸發事件的元素。
如果你使用 ES6 的箭號函式來做為事件處理器,必須特別注意的是,箭號函式的 this
是根據語彙環境,而不是像 function
根據呼叫者是誰來決定。
在 DOM Level 2 事件模型下,Event
會作為事件處理器的第一個參數傳入,有些事件有預設的動作,若要停止預設動作,在 DOM Level 2 事件模型下,必須呼叫 Event
的 preventDefault
方法(而不是像基本事件模型那樣,從事件處理器中傳回 false
)。例如可改寫〈基本事件模型〉中第三個表單驗證範例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<form name="form1" action="fake.do">
輸入資料:<input name="data"><br>
<button type="submit">送出</button>
</form>
<script type="text/javascript">
document.form1.addEventListener('submit', event => {
if(event.currentTarget.data.value.length === 0) {
event.preventDefault();
}
}, false);
</script>
</body>
</html>
若要移除事件處理器,則可以使用 removeEventListener
,第一個參數指定事件類型,第二個參數是當初註冊的函式實例,第三個參數指出要移除捕捉階段(true
)或浮昇階段(false
)的處理器,下一篇文件就會加以說明。