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