1. 程式人生 > >JS事件--事件物件之DOM中的事件物件

JS事件--事件物件之DOM中的事件物件

在觸發DOM上的某個事件時,會產生一個事件物件event,這個物件中包含著所有與事件有關的資訊。包括導致事件的元素、事件的型別以及其他與特定事件相關的資訊。例如,滑鼠操作導致的事件物件中,會包含滑鼠位置的資訊,而鍵盤操作導致的事件物件中,會包含與按下的鍵有關的資訊。所有瀏覽器都支援event物件,但支援方式不同。

相容DOMr瀏覽器會將一event物件傳入到事件處理程式中。無論指定的事件處理程式時使用什麼方式(DOM0級和DOM2級),都會傳入event物件,來看下面的例子


var btn = document.getElementById('myBtn');
btn.onclick = function
(evnet) {
alert(event.type);// click } btn.addEVentListener('click', function(evnet){ alert(event.type);//click }, false);

這個例子中的兩個事件處理程式都會彈出一個警告框,顯示由event.type屬性表示的事件型別。這個屬性始終都會包含被觸發的事件型別,例如:click.

在通過HTML特性指定事件處理程式時,變數event中儲存著event物件。請看下面例子。

<input type="button" value="Click Me" onclick
="alert(event.type)"/>

以這種方式提供event物件,可以讓HTML特性事件處理程式與JavasScript函式執行相同的操作。
event物件包含與建立它的特定事件有關的屬性和方法。觸發的事件型別不一樣,可以用的屬性和方法也不一樣。不過,所有事件都會有下表列出的成員。

屬性/方法 型別 讀/寫 說明
bubbles Boolean 只讀 表明事件是否冒泡
cancellable Boolean 只讀 表明是否可以取消事件的預設行為
currentTarget Element 只讀 其事件處理程式當前正在處理事件的那個元素
defaultPrevented Boolean 只讀 為true表示已經呼叫了preventDefault()(DOM3級事件中新增)
detail Integer 只讀 與事件相關的細節資訊
eventPhase Integer 只讀 呼叫事件處理程式的階段:1表示捕獲階段,2表示處理目標,3表示冒泡階段
preventDefault() Function 只讀 取消事件的預設行為。如果cancelabel是true,則可以使用這個方法
stopImmediatepropagation() Function只讀 取消事件的進一步捕獲或冒泡,同時 阻止任何事件處理程式被呼叫()
topPropagation() Function 只讀 取消事件的進一步捕獲或冒泡,如果bubbles為teue,則是可以使用這個方法
target Element 只讀 事件的目標
trusted Boolean 只讀 為true表示事件是瀏覽器生成的。為false表示事件是由開發人員通過JavasScript建立的(DOM3級事件中新增)
type String 只讀 被觸發的事件的型別
view AbstractView 只讀 與事件關聯的抽象檢視。等同於發生事件的window物件

在事件處理程式內部,物件this始終等於currentTarget的值,而target則只包含事件的實際目標。如果直接將事件處理程式指定給了目標元素,則this,currentTarget和target包含相同的值。來看下面的例子。


var btn = document.getElementById('myBtn');
btn.onclick = function(evnet) {
    alert(event.currentTarget === this);//true
    alert(event.target === this); //true
}

這個例子檢測了currentTarget和target與this的值。由於 click事件的目標是按鈕,因此這三個值是相等的。如果事件處理程式在於按鈕的父點中(例如document.body),那麼這些值是不相同的。再看下面的例子。


var btn = document.getElementById('myBtn');
document.body.onclick = function(evnet) {
    alert(event.currentTarget === document.body);//true
    alert(this === document.body); //true
    alert(event.target === document.getElementById('myBtn'));// true
}

當單擊這個例子中的按鈕時,this和currentTarget都等於document.body,因為事件處理程式是註冊到這個元素上的,然而,target元素卻等於 按鈕元素,因為它是click事件真正的目標。由於 按鈕上並沒有註冊事件處理程式,結果click事件就是早洩到了document.body,在那裡事件才得到了處理。

在需要通過一個函式處理多個事件時,可以使用type屬性,例如:


var btn = document.getElementById('myBtn');

var handler = function(event) {
    switch(event.type) {
        case: 'click':
            alert('Clicked');
            break;
        case: 'mouseouver':
            alert('mouseouver');
            break;
        case: 'mouseout':
            alert('mouseout');
            break;
    }
};

btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

這個例子定義了一個名為handler的函式,用於處理3種事件:click mouseover 和mouseout.當單擊按鈕時,會出現一個與前面例子中一樣的警告框。當按鈕移動到按鈕上面時,背景顏色應該會變成紅色,而當滑鼠移動出按鈕的範圍時,背景顏色應該會恢復為預設值。這裡通過檢測event.type屬性,讓函式能夠確定發生了什麼事件,並執行相應的操作。

要阻止特定的事件的預設行為,可以使用preventDefault()方法。例如,連結的預設行為就是在被單擊時會導航到期href特性指定的URL。如果你想阻止連結導航這一預設行為,那麼通過連結的onclick事件處理程式可以取消它,如下面的例子所示。

var link = document.getElementById('myLink');
link.onclick = function(evnet) {
    event.preventDefault();
}

只有cancelable屬性設定為true的事件,才可以使用prenvetDefault()來取消其預設行為。
另外,stopPropagation()方法用於立即停止事件在DOM層次中的傳播,即取消進一步的事件捕獲或冒泡。例如,直接新增到一個按鈕的事件處理程式可以呼叫stopPropagation(),從而書名觸發註冊在document.body上面的事件處理程式,如下面的例子所示:

var btn = document.getElementById('myBtn');
btn.onclick = function(evnet) {
    alert('Clicked');
    event.stopPropagation();
}

document.body.onclick = function(evnet) {
    alert('Body clicked');
}

對於這個例子而言,如果不呼叫stopPropagation(),就會在單擊按鈕時出現兩個警告框。可是,由於click事件根本 不會傳播到 document.body,因此就不會觸發註冊在這個元素上的onclick事件處理程式。

事件物件的eventPhase屬性,可以用來確定事件當前正們於事件流的那個階段。如果是在捕獲階段呼叫的事件處理程式,那麼eventPhase等於 1;如果事件處理程式處於目標物件上,則eventPhase等於2; 如果是在冒泡階段呼叫的事件處理程式,evevntPhase等於3,這裡要注意的是,儘管處於目標發生在冒泡階段,但eventPhase仍然一直等於 2.來看下面的例子。

var btn = document.getElementById('myBtn');
btn.onclick = function(evnet) {
    alert(event.eventPhase);//2
}

document.body.addEventListener('click', function(event){
    alert(event.eventPhase)///1
}, true);

document.body.onclick = function(evnet) {
    alert(event.eventPhase);//3
}

當單擊這個例子中的按鈕時,首先執行的事件處理程式是在捕獲階段觸發的新增到document.body中的那一個,結果會彈出一個警告框顯示錶示eventPhase的1.接著,會觸發 在按鈕上註冊 的事件處理程式,此時 的eventPhasse值為2,最後一個被觸發的事件處理程式,是在冒泡階段執行的新增到document.body的那一個,顯示eventPhase的值為3.頁當eventPhase等於 2時,this、target和currentTarget始終都是相等的。

只有在事件處理程式執行期間,event物件才會存在;一旦事件處理程式執行完成,event物件就會被銷燬。