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物件就會被銷燬。