事件模型
DOM0級模型
在該模型中,事件不會傳播,沒有事件流的概念。這種模型兼容所有的瀏覽器。事件綁定監聽函數有兩種方式:
<!-- html 內聯直接綁定 -->
<input type="button" onclick="fun()">
//通過js指定屬性值
var btn = document.getElementById('.btn');
btn.onclick = fun;
//移除監聽函數
btn.onclick = null;
IE事件模型
IE事件模型共有兩個過程:
- 事件處理階段,事件到達目標元素,觸發目標元素的監聽函數
- 事件冒泡階段,事件從目標元素冒泡到document, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
//添加監聽
attachEvent(eventType, handler)
//移除監聽
detachEvent(eventType, handler)
/*
* eventType指定事件類型(注意加on)
* handler是事件處理函數
**/
DOM2級模型
屬于W3C標準模型,現代瀏覽器(除IE6-8之外的瀏覽器)都支持該模型。在該事件模型中,一次事件共有三個過程:
- 事件捕獲階段。事件從document一直向下傳播到目標元素,依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
- 事件處理階段。事件到達目標元素,觸發目標元素的監聽函數。
- 事件冒泡階段。事件從目標元素冒泡到document, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
//綁定事件監聽
addEventListener(eventType, handler, useCapture)
//移除事件監聽
removeEventListener(eventType, handler, useCapture)
/**
* eventType指定事件類型(不要加on)
* handler是事件處理函數
* useCapture是一個boolean用于指定是否在捕獲階段進行處理,一般設置為false與IE瀏覽器保持一致。
*/
事件對象
DOM事件模型中的事件對象屬性:
- type用于獲取事件類型
- target獲取事件目標
- stopPropagation()阻止事件冒泡
- preventDefault()阻止事件默認行為
IE事件模型中的事件對象常用屬性:
- type用于獲取事件類型
- srcElement獲取事件目標
- cancelBubble阻止事件冒泡
- returnValue阻止事件默認行為
跨瀏覽器事件處理
var eventUtils={
// 添加句柄
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent('on'+type,handler);
}else{
element['on'+type]=handler;
}
},
// 刪除句柄
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent('on'+type,handler);
}else{
element['on'+type]=null;
}
},
//獲取事件對象
//IE模型中event是一個全局唯一的對象綁定在window對象上
getEvent:function(event){
return event?event:window.event;
},
//獲取類型
getType:function(event){
return event.type;
},
getElement:function(event){
return event.target || event.srcElement;
},
//阻止默認事件
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
//阻止冒泡
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
}
}
事件代理
事件在冒泡過程中會上傳到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件,這種方式被稱為事件代理。
<div id="box">
<input type="button" value="按鈕" id="btn">
<input type="button" value="按鈕2" id="btn2">
<input type="button" value="按鈕3" id="btn3">
</div>
var box = document.getElementById('box');
box.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'input') {
// some code
}
});
自定義事件
以創建以個三擊事件為例
//創建一個事件
var event = new Event('threeclick', {"bubbles":true, "cancelable":false});
//為事件注冊監聽函數
target.addEventListener('threeclick', hello, false);
//觸發函數
target.dispatchEvent(event);