DOM3 級(jí)事件規(guī)定了以下幾類事件:
- UI(User Interface,用戶界面)事件,當(dāng)用戶與頁面上的元素交互時(shí)觸發(fā);
- 焦點(diǎn)事件,當(dāng)元素獲得或失去焦點(diǎn)時(shí)觸發(fā);
- 鼠標(biāo)事件,當(dāng)用戶通過鼠標(biāo)在頁面上執(zhí)行操作時(shí)觸發(fā);
- 滾輪事件,當(dāng)使用鼠標(biāo)滾輪(或類似設(shè)備)時(shí)觸發(fā);
- 文本事件,當(dāng)在文檔中輸入文本時(shí)觸發(fā);
- 鍵盤事件,當(dāng)用戶通過鍵盤在頁面上執(zhí)行操作時(shí)觸發(fā);
- 合成事件,當(dāng)為IME(Input Method Editor,輸入法編輯器)輸入字符時(shí)觸發(fā);
- 變動(dòng)(mutation)事件,當(dāng)?shù)讓?DOM 結(jié)構(gòu)發(fā)生變化時(shí)觸發(fā)。
變動(dòng)名稱事件,當(dāng)元素或?qū)傩悦儎?dòng)時(shí)觸發(fā)。此類事件已經(jīng)被廢棄,沒有任何瀏覽器實(shí)現(xiàn)它們。
UI事件
UI事件指的是那些不一定與用戶操作有關(guān)的事件。
| 事件 | 描述 |
|---|---|
| 元素已經(jīng)被用戶操作(鼠標(biāo)或鍵盤)激活。已被廢棄。 | |
| load | 頁面完全加載完后在window上觸發(fā),所有框架加載完畢后在框架集上觸發(fā),圖像加載完畢在img元素上觸發(fā),當(dāng)嵌入內(nèi)容加載完畢在object元素上觸發(fā)。 |
| unload | 頁面完全卸載(window觸發(fā)),所有框架都卸載后(框架集觸發(fā)),嵌入內(nèi)容卸載完畢后(object觸發(fā))。 |
| abort | 當(dāng)用戶停止下載過程,如果嵌入內(nèi)容沒有加載完,則在object元素上除法。 |
| error | 當(dāng)發(fā)生JavaScript錯(cuò)誤時(shí)(window觸發(fā)),當(dāng)無法加載圖像時(shí)(img觸發(fā)),當(dāng)無法加載嵌入內(nèi)容時(shí)(object觸發(fā)),當(dāng)一或多個(gè)框架無法加載(框架集觸發(fā))。 |
| select | 當(dāng)用戶選擇文本框(texterea或input)中的一個(gè)或多個(gè)字符時(shí)觸發(fā)。 |
| resize | 當(dāng)窗口或框架的大小變化時(shí)在window或框架上觸發(fā)。 |
| scroll | 當(dāng)用戶滾動(dòng)帶滾動(dòng)條的元素中的內(nèi)容時(shí),在該元素上觸發(fā)。 |
多數(shù)這些事件都與window對(duì)象或表單空間相關(guān)。
除了DOMActivate之外,其他事件在 DOM2 級(jí)事件中都?xì)w為HTML事件(DOMActivate在 DOM2 級(jí)中任然屬于UI事件)。
要確定瀏覽器是否支持“DOM3 級(jí)事件”定義的事件,可以使用如下代碼:
var isSupported = document.implementation.hasFeature("UIEvent","3.0");
1、load事件
js中最常用的一個(gè)事件就是load。當(dāng)頁面完全加載后(包括所有圖像、js文件、css文件等外部資源),就會(huì)觸發(fā)window上面的load事件。
有兩種定義onload事件處理程序的方式。
1、使用JavaScript代碼:
EventUtil.addHandler(window,"load",function(event){
alert("Loaded");
});
2、為<body>元素添加一個(gè)onload特性:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<title>Title</title>
</head>
<body onload="alert('Loaded!');">
<body>
</html>
圖像上面也可以觸發(fā)load事件,無論是在DOM元素中的圖像元素還是HTML中的圖像元素。因此可以在HTML中為任何圖像指定onload事件處理程序:
<img src="smile.gif" onload="alert('Image loaded.')">
同樣的功能也可以用javascript完成:
var img = document.getElementById("myImg");
EventUtil.addHandler(img,"load",function(event){
event = EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src);
});
在創(chuàng)建新的< img>元素時(shí),可以為其指定一個(gè)事件處理程序,以便圖像加載完畢后給出提示。此時(shí),最重要的是要在指定src屬性之前先指定事件。
//首先為window指定了onload事件處理程序。
//向DOM中添加一個(gè)新元素,必須確定頁面已經(jīng)加載完畢——如果在頁面加載前操作document.body會(huì)導(dǎo)致錯(cuò)誤。
EventUtil.addHandler(window,"load",function(){
//然后,創(chuàng)建了一個(gè)新的圖像元素,并設(shè)置了其onload事件處理程序。
var image = document.createElement("img");
EventUtil.addHandler(image,"load",function(event){
event = EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src);
});
//最后將這個(gè)圖像添加到頁面中,還設(shè)置了它的src屬性。
document.body.appendChild(image);
image.src = "smile.gif";
//新圖像元素不一定要從添加到文檔后才開始下載,只要設(shè)置了src屬性就會(huì)開始下載。
});
還有一些元素也以非標(biāo)準(zhǔn)的方式支持load事件:
<script>元素也會(huì)觸發(fā)load事件,以便開發(fā)人員確定動(dòng)態(tài)加載的javascript文件是否加載完畢。
與圖像不同,只有在設(shè)置了<script>元素的src屬性并將該元素添加到文檔后,才會(huì)開始下載Javascript文件。換句話說,對(duì)于<script>元素而言,指定src屬性和指定事件處理程序的先后順序就不重要了。
EventUtil.addHandler(window,"load",function(){
var script= document.createElement("script");
EventUtil.addHandler(script,"load",function(event){
alert("loaded");
});
script.src = "example.js";
document.body.appendChild(script);
});
IE和Opera還支持< link>元素上的load事件,以便開發(fā)人員確定樣式表是否加載完畢。
與< script>節(jié)點(diǎn)類似,在未指定href屬性并將< link>元素添加到文檔之前也不會(huì)開始下載樣式表。
2、unload事件
這個(gè)事件在文檔被完全卸載后觸發(fā)。
只要用戶從一個(gè)頁面切換到另一個(gè)頁面,就會(huì)發(fā)生unload事件。而利用這個(gè)事件最多的情況就是清除引用,以避免內(nèi)存泄露。
與load事件類似,也有兩種指定onunload事件處理程序的方式:
1、使用JavaScript代碼:
EventUtil.addHandler(window,"unload",function(event){
alert("Unloaded");
//此時(shí)生成的event對(duì)象在兼容DOM的瀏覽器中只包含target屬性(值為document)。
//IE8 及之前版本則為這個(gè)事件對(duì)象提供了 srcElement 屬性。
});
2、為<body>元素添加一個(gè)onunload特性:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<title>Title</title>
</head>
<body onunload="alert('Unloaded!');">
<body>
</html>
3、resize事件
當(dāng)瀏覽器窗口被調(diào)整到一個(gè)新的高度或?qū)挾葧r(shí),就會(huì)觸發(fā)resize事件。
這個(gè)事件在window上面觸發(fā),因此可以通過Javascript或者<body>元素中的onresize特性來指定事件處理程序。
EventUtil.addHandler(window,"resize",function(event){
alert("resize");
});
在兼容DOM的瀏覽器中,event.target = document;而 IE8 及之前的版本則未提供任何屬性。
關(guān)于何時(shí)會(huì)觸發(fā)resize事件,不同的瀏覽器有不同的機(jī)制:
Firefox:只會(huì)在用戶停止調(diào)整窗口大小時(shí)才會(huì)觸發(fā)resize事件。
其他瀏覽器:只要瀏覽器窗口變化了1像素時(shí)就觸發(fā),然后隨著變化不斷重復(fù)觸發(fā)。
由于存在這個(gè)差別,應(yīng)該注意不要在這個(gè)事件的處理程序中加入大計(jì)算量的代碼,因?yàn)檫@些代碼有可能被頻繁執(zhí)行,從而導(dǎo)致瀏覽器反應(yīng)明顯變慢。
瀏覽器窗口最小化或最大化時(shí)也會(huì)觸發(fā)resize事件。
4、scroll事件
雖然scroll事件是在window對(duì)象上發(fā)生的,但它實(shí)際表示的則是頁面中相應(yīng)元素的變化。
在混雜模式下,可以通過<body>元素的scrollLeft和scrollTop來監(jiān)控這一變化。 在標(biāo)準(zhǔn)模式下,除了Safari之外的所有瀏覽器都會(huì)通過<html>元素來反映這一變化。
EventUtil.addHandler(window,"scroll",function(event){
if(document.compatMode == "CSS1Compat"){
alert(document.documentElement.scrollTop;
} else {
alert(document.body.scrollTop);
}
});
與resize事件類似,scroll事件也會(huì)在文檔被滾動(dòng)期間重復(fù)被觸發(fā),所以有必要盡量保持事件處理程序的代碼簡單。
焦點(diǎn)事件
焦點(diǎn)事件會(huì)在頁面元素獲得或失去焦點(diǎn)時(shí)觸發(fā)。
利用這些事件并與document.hasFocus()方法及document.activeElement屬性配合,可以知曉用戶在頁面上的行蹤。
| 事件 | 描述 |
|---|---|
| blur | 在元素失去焦點(diǎn)時(shí)觸發(fā),這個(gè)事件不會(huì)冒泡。 |
| focus | 在元素獲得焦點(diǎn)時(shí)觸發(fā),這個(gè)事件不會(huì)冒泡。 |
| focusin | 在元素獲得焦點(diǎn)時(shí)觸發(fā),與HTML事件focus等價(jià),但它冒泡。 |
| focusout | 在元素失去焦點(diǎn)時(shí)觸發(fā),這個(gè)事件是HTML事件blur的通用版本。 |
| 在元素獲得焦點(diǎn)時(shí)觸發(fā)。DOM3 級(jí)事件廢棄了DOMFocusIn,選擇了focusin。 | |
| 在元素失去焦點(diǎn)時(shí)觸發(fā)。DOM3 級(jí)事件廢棄了DOMFocusIn,選擇了focusout。 |
這一類事件中最主要的兩個(gè)是focus和blur,他們都是JavaScript早期就得到所有瀏覽器支持的事件,但它們不冒泡,因此才會(huì)有focusin和focusout被納入標(biāo)準(zhǔn)方式。
當(dāng)焦點(diǎn)從頁面的一個(gè)元素移動(dòng)到另一個(gè)元素,會(huì)依次觸發(fā)下列事件:
- focusout:在失去焦點(diǎn)的元素上觸發(fā)
- focusin:在獲得焦點(diǎn)的元素上觸發(fā)
- blur:在失去焦點(diǎn)的元素上觸發(fā)
- focus:在獲得焦點(diǎn)的元素上觸發(fā)
其中,focusout和blur的事件目標(biāo)是失去焦點(diǎn)的元素;focus和focusin的事件目標(biāo)是獲得焦點(diǎn)的元素。
鼠標(biāo)與滾輪事件
鼠標(biāo)事件是web開發(fā)中最常用的一類事件。
DOM3級(jí)事件中定義了9個(gè)鼠標(biāo)事件:
| 事件 | 描述 |
|---|---|
| click | 在用戶單擊主鼠標(biāo)按鈕或按下回車鍵時(shí)觸發(fā)。這意味著onclick事件處理程序即可以通過鍵盤也可以通過鼠標(biāo)執(zhí)行。 |
| dbclick: | 在用戶雙擊主鼠標(biāo)按鈕時(shí)觸發(fā)。 |
| mousedown | 用戶按下了任意鼠標(biāo)按鈕時(shí)觸發(fā),不能通過鍵盤觸發(fā)這個(gè)事件。 |
| mouseenter | 在鼠標(biāo)光標(biāo)從元素外部首次移動(dòng)到元素范圍之內(nèi)時(shí)觸發(fā)。這個(gè)事件不冒泡,而且在光標(biāo)移動(dòng)到后代元素上不會(huì)觸發(fā)。 |
| mouseleave | 在位于元素上方的鼠標(biāo)光標(biāo)移動(dòng)到元素范圍之外時(shí)觸發(fā)。這個(gè)事件不冒泡,而且在光標(biāo)移動(dòng)到后代元素上不會(huì)觸發(fā)。 |
| mousemove | 當(dāng)鼠標(biāo)指針在元素內(nèi)部移動(dòng)時(shí)重復(fù)地觸發(fā)。不能通過鍵盤觸發(fā)這個(gè)事件。 |
| mouseout | 在鼠標(biāo)指針位于一個(gè)元素上方,然后用戶將其移入另一個(gè)元素時(shí)觸發(fā)。又移入另一個(gè)元素可能位于前一個(gè)元素的外部,也可能是這個(gè)元素的子元素。不能通過鍵盤觸發(fā)這個(gè)事件。 |
| mouseover | 在鼠標(biāo)指針位于一個(gè)元素外部,然后用戶將其首次移入另一個(gè)元素邊界之內(nèi)時(shí)觸發(fā)。不能通過鍵盤觸發(fā)這個(gè)事件。 |
| mouseup | 在用戶釋放鼠標(biāo)按鈕時(shí)觸發(fā)。不能通過鍵盤觸發(fā)這個(gè)事件。 |
頁面上所有元素都支持鼠標(biāo)事件。除了mouseenter和mouseleave,所有鼠標(biāo)事件都會(huì)冒泡,也可以被取消。
- 只有在同一個(gè)元素上相繼觸發(fā)mousedown和mouseup事件,才會(huì)觸發(fā)click事件;
- 如果mousedown或mouseup中的一個(gè)被取消,就不會(huì)觸發(fā)click事件;
- 只有觸發(fā)兩次click事件,才會(huì)觸發(fā)一次dbclick事件;
- 如果有代碼阻止了連續(xù)兩次觸發(fā)click事件,那么就不會(huì)觸發(fā)dbclick事件了。
這4個(gè)事件觸發(fā)的順序始終如下:
- mousedown
- mouseup
- click
- mousedown
- mouseup
- click
- dbclick
click和dbclick都會(huì)依賴與其他先行事件的觸發(fā);而mousedown和mouseup則不受其他事件影響。
鼠標(biāo)事件中還有一個(gè)滾輪事件mousewheel,這個(gè)事件跟蹤鼠標(biāo)滾輪。