[TOC]
## 10.4 事件類型
Web瀏覽器中可能發生的事件又很多類型,不同的事件類型具有不同的信息。
| 事件類型 | 觸發時刻 |
| --- | --- |
| UI | 當用戶與頁面上的元素交互時觸發 |
| 焦點 | 當元素獲得或失去焦點時觸發 |
| 鼠標 | 當用戶通過鼠標在頁面上執行操作時觸發 |
| 滾輪 | 當使用鼠標滾輪(或類似設備)時觸發 |
| 文本 | 當在文檔中輸入文本時觸發 |
| 鍵盤 | 當用戶通過鍵盤在頁面上執行操作時觸發 |
| 合成 | 當為IME(輸入法編輯器)輸入字符時觸發 |
| 變動 | 當底層DOM結構發生變化時觸發 |
HTML5也定義了一組事件,而有些瀏覽器還會在DOM和BOM中實現其他專有事件。
### 10.4.1 UI事件
UI事件:指不一定與用戶操作有關的事件。
**1. load事件**
當頁面完全加載后(包括所有圖像、JavaScript文件、CSS文件等外部資源),就會觸發window上面的load事件。
兩種定義onload事件處理程序的方式:
* 使用JS代碼(推薦)
~~~
EventUtil.addHandler(window,"load",function(event){
alert("Loaded!");
});
~~~
* 為<body>元素添加一個onload特性(一般,在window上面發生的任何事件都可以在<body>元素中通過相應的特性來指定,因為HTML中無法訪問window元素)
`<img>`元素也可以
~~~
<img src="smile.gif" onload="alert('Image loaded.')">
~~~
**2. unload事件**
在文檔被完全卸載后觸發,只要用戶從一個頁面切換到另一個頁面,就會發生unload事件。利用這個事件最多的情況是清除引用,以避免內存泄漏。
**3. resize事件**
當瀏覽器窗口被調整到一個新的高度或寬度時,就會觸發。這個事件在window上面觸發。
**4. scroll事件**
雖然scroll事件時在window對象上發生的,但它實際表示的則是頁面中相應元素的變化。在混雜模式下,可以通過<body>元素的scrollLeft和scrollTop來監控到這一變化;而在標準模式下,除了Safari之外的所有瀏覽器都會通過<html>元素來反應這一變化。
### 10.4.2 焦點事件
焦點事件會在頁面元素獲得或失去焦點時觸發。利用這些事件并與document.hasFocus*(方法及document.activeElement屬性配合,可以知曉用戶在頁面上的行蹤。
焦點事件發生在Element節點和document對象上。
|||
|---|---|
| focus事件 | Element節點獲得焦點后觸發,該事件不會冒泡。|
| blur事件 | Element節點失去焦點后觸發,該事件不會冒泡。|
| focusin事件 | Element節點將要獲得焦點時觸發,發生在focus事件之前。該事件會冒泡。Firefox不支持該事件。|
| focusout事件 | Element節點將要失去焦點時觸發,發生在blur事件之前。該事件會冒泡。Firefox不支持該事件。|
* 這四個事件的事件對象,帶有target屬性(返回事件的目標節點)和relatedTarget屬性(返回一個Element節點)。對于focusin事件,relatedTarget屬性表示失去焦點的節點;對于focusout事件,表示將要接受焦點的節點;對于focus和blur事件,該屬性返回null。
* 由于focus和blur事件不會冒泡,只能在捕獲階段觸發,所以addEventListener方法的第三個參數需要設為true。
### 10.4.3 鼠標與滾輪事件
|||
|||
| click | click事件當用戶在Element節點、document節點、window對象上,單擊鼠標(或者按下回車鍵)時觸發。“鼠標單擊”定義為,用戶在同一個位置完成一次mousedown動作和mouseup動作。它們的觸發順序是:mousedown首先觸發,mouseup接著觸發,click最后觸發。|
| dblclick | dblclick事件當用戶在element、document、window對象上,雙擊鼠標時觸發。該事件會在mousedown、mouseup、click之后觸發。|
| mousedown | mousedown事件在按下鼠標鍵時觸發。|
| mouseup | mouseup事件在釋放按下的鼠標鍵時觸發。 |
| mousemove | mousemove事件當鼠標在一個節點內部移動時重復地觸發。當鼠標持續移動時,該事件會連續觸發。為了避免性能問題,建議對該事件的監聽函數做一些限定,比如限定一段時間內只能運行一次代碼。|
| mouseover、mouseenter | 都是鼠標進入一個節點時觸發。兩者的區別是,mouseenter事件只觸發一次,而只要鼠標在節點內部移動,mouseover事件會在子節點上觸發多次。|
| mouseout、mouseleave | mouseout事件和mouseleave事件,都是鼠標離開一個節點時觸發。|
除了“mouseenter”和“mouseleave”外的所有鼠標事件都能**冒泡**。
**1. 客戶區坐標位置**
鼠標事件都是在瀏覽器視口中的特定位置上發生的。這個位置信息保存在事件對象的**clientX和clientY屬性**中。所有瀏覽器都支持這兩個屬性,他們的值表示事件發生時鼠標指針在視口中的水平和垂直坐標。(不包括頁面滾動距離)
**2. 頁面坐標位置**
頁面坐標通過事件對象的**pageX和pageY屬性**,表示事件在頁面中的什么位置發生。
在頁面沒有滾動的情況下,pageX和pageY的值與clientX和clientY的值相等。
不支持頁面坐標,可使用客戶區坐標和滾動信息計算:
~~~
pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
~~~
**3. 屏幕坐標位置**
通過screenX和screenY屬性就可以確定鼠標事件發生時鼠標指針相對于整個屏幕的坐標信息。
**4. 修改鍵**
DOM規定了4個屬性,表示相關修改鍵的狀態:**shifKey、ctrlKey、altKey和metaKey。(布爾值)**
**5. 相關元素**
在發生mouseover和mouseout事件時,還會涉及更多的元素。這兩個事件都會涉及把鼠標直接從一個元素的邊界之內移動到另一個元素的邊界之內。
**relatedTarget屬性**返回事件的次要相關節點。對于那些沒有次要相關節點的事件,該屬性返回null。
**6. 鼠標按鈕**
DOM的button屬性
-1:沒有按下鍵。
0:按下主鍵(通常是左鍵)。
1:按下輔助鍵(通常是中鍵或者滾輪鍵)。
2:按下次鍵(通常是右鍵)。
IE的button屬性
返回一個3個比特位的值,表示同時按下了哪些鍵。它用來處理同時按下多個鼠標鍵的情況。
1:二進制為001,表示按下左鍵。
2:二進制為010,表示按下右鍵。
4:二進制為100,表示按下中鍵或滾輪鍵。
同時按下多個鍵的時候,每個按下的鍵對應的比特位都會有值。比如,同時按下左鍵和右鍵,會返回3(二進制為011)。
**7. 鼠標滾輪事件**
* 所有的現代瀏覽器都支持鼠標滾輪,并在用戶滾動滾輪時觸發事件。
* 瀏覽器通常使用鼠標滾輪滾動或縮放文檔,但可以通過取消mousewheel事件來阻止這些默認操作。
* 所有瀏覽器都支持“mousewheel”事件,但Firefox使用“DOMMouseScroll”事件。
*傳遞給“mousewheel”處理程序的事件對象有**wheelDelta屬性**,其指定用戶滾動滾輪有多遠(根據這個判斷滾動方向)。遠離用戶方向的一次鼠標滾輪“單擊”的wheelDelta值通常是120,而接近用戶方向的一次“單擊”的值是-120。返回的總是120的倍數(120表明mouse向上滾動,-120表明鼠標向下滾動)
而在Firefox中,傳遞給“DOMMouseScroll”的屬性是detail。不過, detail屬性值的縮放比率和正負符號不同wheelDelta,detail值乘以-40和wheelDelta值相等。記錄其滾動距離的是“detail”屬性,它返回的是3的倍數(3表明mouse向下滾動,-3表明mouse向上滾動)。
~~~
window.onmousewheel = document.onmousewheel = scrollWheel;
function scrollWheel(e){
e = e || window.event;
if(e.wheelDelta) { //判斷瀏覽器IE,谷歌滑輪事件
if(e.wheelDelta > 0) {
//當滑輪向上滾動時
} else if(e.wheelDelta < 0) {
//當滑輪向下滾動時
};
} else if(e.detail) { //Firefox滑輪事件
if(e.detail < 0) {
//當滑輪向上滾動時
} else if(e.detail > 0) {
//當滑輪向下滾動時
};
};
}
~~~
### 10.4.4 鍵盤與文本事件
鍵盤事件用來描述鍵盤行為,主要有keydown、keypress、keyup三個事件。
**keydown**:按下鍵盤時觸發該事件。
**keypress**:只要按下的鍵并非Ctrl、Alt、Shift和Meta,就接著觸發keypress事件。
**keyup**:松開鍵盤時觸發該事件。
**文本事件textinput**:任何時候,只要用戶輸入文本都會觸發。在Webkit瀏覽器中支持“textInput”事件。
* 注意:keypress和textinput事件是在新輸入的文本真正插入到聚焦的文檔元素前觸發的。
* 如果用戶一直按鍵不松開,就會重復觸發keydown、keypress,直到用戶松開才會觸發keyup。
**1. 鍵碼**
在發生keydown和keyup事件時,event對象的**keycode屬性**指定了輸入字符的編碼(與ASCII碼相同)。
**2. 字符編碼**
charcode屬性,只有發生keypress事件時才包含該值(等于按鍵字符的ASCII碼)。
String.fromCharCode():一個keypress事件表示輸入的單個字符。事件對象以數字Unicode編碼的形式指定字符,所以必須用String.fromChatCode()把它轉換成字符串。
**3. textInput事件**
當用戶在可編輯區域中輸入字符時,就會觸發這個事件。
與keypress事件不同點:
* 任何可以獲取焦點的元素都可以觸發keypress事件,但只有可編輯區域才能觸發textInput事件。
* textInput事件只會在用戶按下能夠輸入實際字符的鍵時才會被觸發,而keypress事件則在按下那些能夠影響文本顯示的鍵時才會觸發(如退格鍵)。
### 10.4.5 HTML事件
**1. contextmenu事件**
* 用以表示何時應該顯示上下文菜單,以便開發人員取消默認的上下文菜單而**提供自定義的菜單**。
* 由于contextmenu事件時冒泡的,因此可以為document指定一個事件處理程序,用以處理頁面中發生的所有此類事件。
* 通常使用contextmenu事件來顯示自定義的上下文菜單,而是用onclick事件處理程序來隱藏該菜單。
**2. beforeunload事件**
為了讓開發人員有可能在頁面卸載前阻止這一操作。
**3. DOMContentLoaded事件**
在形成完整的Dom樹之后就會觸發,不理會圖像、JavaScript文件、CSS文件或其他資源是否已經下載完畢。即支持在頁面下載的早期添加事件處理程序,意味著用戶能夠盡早地與頁面進行交互。
**4. haschange事件**
便于在URL的參數列表(及URL中“#”號后面的所有字符串)發生變化時通知開發人員。
- 前言
- 第一章 JavaScript簡介
- 第三章 基本概念
- 3.1-3.3 語法、關鍵字和變量
- 3.4 數據類型
- 3.5-3.6 操作符、流控制語句(暫略)
- 3.7函數
- 第四章 變量的值、作用域與內存問題
- 第五章 引用類型
- 5.1 Object類型
- 5.2 Array類型
- 5.3 Date類型
- 5.4 基本包裝類型
- 5.5 單體內置對象
- 第六章 面向對象的程序設計
- 6.1 理解對象
- 6.2 創建對象
- 6.3 繼承
- 第七章 函數
- 7.1 函數概述
- 7.2 閉包
- 7.3 私有變量
- 第八章 BOM
- 8.1 window對象
- 8.2 location對象
- 8.3 navigator、screen與history對象
- 第九章 DOM
- 9.1 節點層次
- 9.2 DOM操作技術
- 9.3 DOM擴展
- 9.4 DOM2和DOM3
- 第十章 事件
- 10.1 事件流
- 10.2 事件處理程序
- 10.3 事件對象
- 10.4 事件類型
- 第十一章 JSON
- 11.1-11.2 語法與序列化選項
- 第十二章 正則表達式
- 12.1 創建正則表達式
- 12.2-12.3 模式匹配與RegExp對象
- 第十三章 Ajax
- 13.1 XMLHttpRequest對象
- 你不知道的JavaScript
- 一、作用域與閉包
- 1.1 作用域
- 1.2 詞法作用域
- 1.3 函數作用域與塊作用域
- 1.4 提升
- 1.5 作用域閉包
- 二、this與對象原型
- 2.1 關于this
- 2.2 全面解析this
- 2.3 對象
- 2.4 混合對象“類”
- 2.5 原型
- 2.6 行為委托
- 三、類型與語法
- 3.1 類型
- 3.2 值
- 3.3 原生函數