# EventTarget 接口
事件的本質是程序各個組成部分之間的一種通信方式,也是異步編程的一種實現。DOM 支持大量的事件,本章開始介紹 DOM 的事件編程。
## 概述
DOM 的事件操作(監聽和觸發),都定義在`EventTarget`接口。所有節點對象都部署了這個接口,其他一些需要事件通信的瀏覽器內置對象(比如,`XMLHttpRequest`、`AudioNode`、`AudioContext`)也部署了這個接口。
該接口主要提供三個實例方法。
- `addEventListener`:綁定事件的監聽函數
- `removeEventListener`:移除事件的監聽函數
- `dispatchEvent`:觸發事件
## EventTarget.addEventListener()
`EventTarget.addEventListener()`用于在當前節點或對象上,定義一個特定事件的監聽函數。一旦這個事件發生,就會執行監聽函數。該方法沒有返回值。
```javascript
target.addEventListener(type, listener[, useCapture]);
```
該方法接受三個參數。
- `type`:事件名稱,大小寫敏感。
- `listener`:監聽函數。事件發生時,會調用該監聽函數。
- `useCapture`:布爾值,表示監聽函數是否在捕獲階段(capture)觸發(參見后文《事件的傳播》部分),默認為`false`(監聽函數只在冒泡階段被觸發)。該參數可選。
下面是一個例子。
```javascript
function hello() {
console.log('Hello world');
}
var button = document.getElementById('btn');
button.addEventListener('click', hello, false);
```
上面代碼中,`button`節點的`addEventListener`方法綁定`click`事件的監聽函數`hello`,該函數只在冒泡階段觸發。
關于參數,有兩個地方需要注意。
首先,第二個參數除了監聽函數,還可以是一個具有`handleEvent`方法的對象。
```javascript
buttonElement.addEventListener('click', {
handleEvent: function (event) {
console.log('click');
}
});
```
上面代碼中,`addEventListener`方法的第二個參數,就是一個具有`handleEvent`方法的對象。
其次,第三個參數除了布爾值`useCapture`,還可以是一個屬性配置對象。該對象有以下屬性。
> - `capture`:布爾值,表示該事件是否在`捕獲階段`觸發監聽函數。
> - `once`:布爾值,表示監聽函數是否只觸發一次,然后就自動移除。
> - `passive`:布爾值,表示監聽函數不會調用事件的`preventDefault`方法。如果監聽函數調用了,瀏覽器將忽略這個要求,并在監控臺輸出一行警告。
如果希望事件監聽函數只執行一次,可以打開屬性配置對象的`once`屬性。
```javascript
element.addEventListener('click', function (event) {
// 只執行一次的代碼
}, {once: true});
```
`addEventListener`方法可以為針對當前對象的同一個事件,添加多個不同的監聽函數。這些函數按照添加順序觸發,即先添加先觸發。如果為同一個事件多次添加同一個監聽函數,該函數只會執行一次,多余的添加將自動被去除(不必使用`removeEventListener`方法手動去除)。
```javascript
function hello() {
console.log('Hello world');
}
document.addEventListener('click', hello, false);
document.addEventListener('click', hello, false);
```
執行上面代碼,點擊文檔只會輸出一行`Hello world`。
如果希望向監聽函數傳遞參數,可以用匿名函數包裝一下監聽函數。
```javascript
function print(x) {
console.log(x);
}
var el = document.getElementById('div1');
el.addEventListener('click', function () { print('Hello'); }, false);
```
上面代碼通過匿名函數,向監聽函數`print`傳遞了一個參數。
監聽函數內部的`this`,指向當前事件所在的那個對象。
```javascript
// HTML 代碼如下
// <p id="para">Hello</p>
var para = document.getElementById('para');
para.addEventListener('click', function (e) {
console.log(this.nodeName); // "P"
}, false);
```
上面代碼中,監聽函數內部的`this`指向事件所在的對象`para`。
## EventTarget.removeEventListener()
`EventTarget.removeEventListener`方法用來移除`addEventListener`方法添加的事件監聽函數。該方法沒有返回值。
```javascript
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
```
`removeEventListener`方法的參數,與`addEventListener`方法完全一致。它的第一個參數“事件類型”,大小寫敏感。
注意,`removeEventListener`方法移除的監聽函數,必須是`addEventListener`方法添加的那個監聽函數,而且必須在同一個元素節點,否則無效。
```javascript
div.addEventListener('click', function (e) {}, false);
div.removeEventListener('click', function (e) {}, false);
```
上面代碼中,`removeEventListener`方法無效,因為監聽函數不是同一個匿名函數。
```javascript
element.addEventListener('mousedown', handleMouseDown, true);
element.removeEventListener("mousedown", handleMouseDown, false);
```
上面代碼中,`removeEventListener`方法也是無效的,因為第三個參數不一樣。
## EventTarget.dispatchEvent()
`EventTarget.dispatchEvent`方法在當前節點上觸發指定事件,從而觸發監聽函數的執行。該方法返回一個布爾值,只要有一個監聽函數調用了`Event.preventDefault()`,則返回值為`false`,否則為`true`。
```javascript
target.dispatchEvent(event)
```
`dispatchEvent`方法的參數是一個`Event`對象的實例(詳見《Event 對象》章節)。
```javascript
para.addEventListener('click', hello, false);
var event = new Event('click');
para.dispatchEvent(event);
```
上面代碼在當前節點觸發了`click`事件。
如果`dispatchEvent`方法的參數為空,或者不是一個有效的事件對象,將報錯。
下面代碼根據`dispatchEvent`方法的返回值,判斷事件是否被取消了。
```javascript
var canceled = !cb.dispatchEvent(event);
if (canceled) {
console.log('事件取消');
} else {
console.log('事件未取消');
}
```
- 前言
- 入門篇
- 導論
- 歷史
- 基本語法
- 數據類型
- 概述
- null,undefined 和布爾值
- 數值
- 字符串
- 對象
- 函數
- 數組
- 運算符
- 算術運算符
- 比較運算符
- 布爾運算符
- 二進制位運算符
- 其他運算符,運算順序
- 語法專題
- 數據類型的轉換
- 錯誤處理機制
- 編程風格
- console 對象與控制臺
- 標準庫
- Object 對象
- 屬性描述對象
- Array 對象
- 包裝對象
- Boolean 對象
- Number 對象
- String 對象
- Math 對象
- Date 對象
- RegExp 對象
- JSON 對象
- 面向對象編程
- 實例對象與 new 命令
- this 關鍵字
- 對象的繼承
- Object 對象的相關方法
- 嚴格模式
- 異步操作
- 概述
- 定時器
- Promise 對象
- DOM
- 概述
- Node 接口
- NodeList 接口,HTMLCollection 接口
- ParentNode 接口,ChildNode 接口
- Document 節點
- Element 節點
- 屬性的操作
- Text 節點和 DocumentFragment 節點
- CSS 操作
- Mutation Observer API
- 事件
- EventTarget 接口
- 事件模型
- Event 對象
- 鼠標事件
- 鍵盤事件
- 進度事件
- 表單事件
- 觸摸事件
- 拖拉事件
- 其他常見事件
- GlobalEventHandlers 接口
- 瀏覽器模型
- 瀏覽器模型概述
- window 對象
- Navigator 對象,Screen 對象
- Cookie
- XMLHttpRequest 對象
- 同源限制
- CORS 通信
- Storage 接口
- History 對象
- Location 對象,URL 對象,URLSearchParams 對象
- ArrayBuffer 對象,Blob 對象
- File 對象,FileList 對象,FileReader 對象
- 表單,FormData 對象
- IndexedDB API
- Web Worker
- 附錄:網頁元素接口
- a
- img
- form
- input
- button
- option
- video,audio