天天看點

JavaScript 事件對象

一.事件對象

事件處理三部分組成:對象.事件處理函數=函數。例如:單擊文檔任意處。

document.onclick = function () {

alert('Lee');

};

PS:以上程式的名詞解釋:click表示一個事件類型,單擊。onclick表示一個事件處理函數或綁定對象的屬性(或者叫事件監聽器、偵聽器)。document表示一個綁定的對象,用于觸發某個元素區域。function()匿名函數是被執行的函數,用于觸發後執行。

除了用匿名函數的方法作為被執行的函數,也可以設定成獨立的函數。

document.onclick = box;//直接指派函數名即可,無須括号

function box() {

alert('Lee');

}

this關鍵字和上下文

在面向對象那章我們了解到:在一個對象裡,由于作用域的關系,this代表着離它最近對象。

var input = document.getElementsByTagName('input')[0];

input.onclick = function () {

alert(this.value);//HTMLInputElement,this表示input對象

};

從上面的拆分,我們并沒有發現本章的重點:事件對象。那麼事件對象是什麼?它在哪裡呢?當觸發某個事件時,會産生一個事件對象,這個對象包含着所有與事件有關的資訊。包括導緻事件的元素、事件的類型、以及其它與特定事件相關的資訊。

事件對象,我們一般稱作為event對象,這個對象是浏覽器通過函數把這個對象作為參數傳遞過來的。那麼首先,我們就必須驗證一下,在執行函數中沒有傳遞參數,是否可以得到隐藏的參數。

function box() {//普通空參函數

alert(arguments.length);//0,沒有得到任何傳遞的參數

}

input.onclick = function () {//事件綁定的執行函數

alert(arguments.length);//1,得到一個隐藏參數

};

通過上面兩組函數中,我們發現,通過事件綁定的執行函數是可以得到一個隐藏參數的。說明,浏覽器會自動配置設定一個參數,這個參數其實就是event對象。

input.onclick = function () {

alert(arguments[0]);//MouseEvent,滑鼠事件對象

};

上面這種做法比較累,那麼比較簡單的做法是,直接通過接收參數來得到即可。

input.onclick = function (evt) {//接受event對象,名稱不一定非要event

alert(evt);//MouseEvent,滑鼠事件對象

};

直接接收event對象,是W3C的做法,IE不支援,IE自己定義了一個event對象,直接在window.event擷取即可。

input.onclick = function (evt) {

var e = evt || window.event;//實作跨浏覽器相容擷取event對象

alert(e);

};

二.滑鼠事件

滑鼠事件是Web上面最常用的一類事件,畢竟滑鼠還是最主要的定位裝置。那麼通過事件對象可以擷取到滑鼠按鈕資訊和螢幕坐标擷取等。

1.滑鼠按鈕

隻有在主滑鼠按鈕被單擊時(正常一般是滑鼠左鍵)才會觸發click事件,是以檢測按鈕的資訊并不是必要的。但對于mousedown和mouseup事件來說,則在其event對象存在一個button屬性,表示按下或釋放按鈕。

非IE(W3C)中的button屬性

說明
表示主滑鼠按鈕(正常一般是滑鼠左鍵)
1 表示中間的滑鼠按鈕(滑鼠滾輪按鈕)
2 表示次滑鼠按鈕(正常一般是滑鼠右鍵)

IE中的button屬性

說明
表示沒有按下按鈕
1 表示主滑鼠按鈕(正常一般是滑鼠左鍵)
2 表示次滑鼠按鈕(正常一般是滑鼠右鍵)
3 表示同時按下了主、次滑鼠按鈕
4 表示按下了中間的滑鼠按鈕
5 表示同時按下了主滑鼠按鈕和中間的滑鼠按鈕
6 表示同時按下了次滑鼠按鈕和中間的滑鼠按鈕
7 表示同時按下了三個滑鼠按鈕

PS:在絕大部分情況下,我們最多隻使用主次中三個單擊鍵,IE給出的其他組合鍵一般無法使用上。是以,我們隻需要做上這三種相容即可。

function getButton(evt) {//跨浏覽器左中右鍵單擊相應

var e = evt || window.event;

if (evt) {//Chrome浏覽器支援W3C和IE

return e.button;//要注意判斷順序

} else if (window.event) {

switch(e.button) {

case 1 :

return 0;

case 4 : 

return 1;

case 2 : 

return 2;

}

}

}

document.onmouseup = function (evt) {//調用

if (getButton(evt) == 0) {

alert('按下了左鍵!');

} else if (getButton(evt) == 1) {

alert('按下了中鍵!');

} else if (getButton(evt) == 2) {

alert('按下了右鍵!' );

}

};

2.可視區及螢幕坐标

事件對象提供了兩組來擷取浏覽器坐标的屬性,一組是頁面可視區左邊,另一組是螢幕坐标。

坐标屬性

屬性 說明
clientX 可視區X坐标,距離左邊框的位置
clientY 可視區Y坐标,距離上邊框的位置
screenX 螢幕區X坐标,距離左螢幕的位置
screenY 螢幕區Y坐标,距離上螢幕的位置

document.onclick = function (evt) {

var e = evt || window.event;

alert(e.clientX + ',' + e.clientY);

alert(e.screenX + ',' + e.screenY);

};

3.修改鍵

有時,我們需要通過鍵盤上的某些鍵來配合滑鼠來觸發一些特殊的事件。這些鍵為:Shfit、Ctrl、Alt和Meat(Windows中就是Windows鍵,蘋果機中是Cmd鍵),它們經常被用來修改滑鼠事件和行為,是以叫修改鍵。

修改鍵屬性

屬性 說明
shiftKey 判斷是否按下了Shfit鍵
ctrlKey 判斷是否按下了ctrlKey鍵
altKey 判斷是否按下了alt鍵
metaKey 判斷是否按下了windows鍵,IE不支援

function getKey(evt) {

var e = evt || window.event;

var keys = [];

if (e.shiftKey) keys.push('shift');//給數組添加元素

if (e.ctrlKey) keys.push('ctrl');

if (e.altKey) keys.push('alt');

return keys;

}

document.onclick = function (evt) {

alert(getKey(evt));

};

三.鍵盤事件

使用者在使用鍵盤時會觸發鍵盤事件。“DOM2級事件”最初規定了鍵盤事件,結果又删除了相應的内容。最終還是使用最初的鍵盤事件,不過IE9已經率先支援“DOM3”級鍵盤事件。

1.鍵碼

在發生keydown和keyup事件時,event對象的keyCode屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字元集,keyCode屬性的值與ASCII碼中對應小寫字母或數字的編碼相同。字母中大小寫不影響。

document.onkeydown = function (evt) {

alert(evt.keyCode);//按任意鍵,得到相應的keyCode

};

不同的浏覽器在keydown和keyup事件中,會有一些特殊的情況:

在Firefox和Opera中,分号鍵時keyCode值為59,也就是ASCII中分号的編碼;而IE和Safari傳回186,即鍵盤中按鍵的鍵碼。

PS:其他一些特殊情況由于浏覽器版本太老和市場佔有率太低,這裡不做補充。

2.字元編碼

Firefox、Chrome和Safari的event對象都支援一個charCode屬性,這個屬性隻有在發生keypress事件時才包含值,而且這個值是按下的那個鍵所代表字元的ASCII編碼。此時的keyCode通常等于0或者也可能等于所按鍵的編碼。IE和Opera則是在keyCode中儲存字元的ASCII編碼。

function getCharCode(evt) {

var e = evt || window.event;

if (typeof e.charCode == 'number') {

return e.charCode;

} else {

return e.keyCode;

}

}

PS:可以使用String.fromCharCode()将ASCII編碼轉換成實際的字元。

keyCode和charCode差別如下:比如當按下“a鍵(重視是小寫的字母)時,

在Firefox中會獲得

keydown: keyCode is 65  charCode is 0

keyup:   keyCode is 65 charCode is 0

keypress: keyCode is 0  charCode is 97

在IE中會獲得

keydown: keyCode is 65  charCode is undefined

keyup:   keyCode is 65  charCode is undefined

keypress: keyCode is 97  charCode is undefined

而當按下shift鍵時,在Firefox中會獲得

keydown:keyCode is 16  charCode is 0

keyup: keyCode is 16   charCode is 0

在IE中會獲得

keydown:keyCode is 16  charCode is undefined

keyup: keyCode is 16  charCode is undefined

keypress:不會獲得任何的charCode值,因為按shift并沒輸入任何的字元,并且也不會觸發keypress事務

PS:在keydown事務裡面,事務包含了keyCode – 使用者按下的按鍵的實體編碼。

在keypress裡,keyCode包含了字元編碼,即默示字元的ASCII碼。如許的情勢實用于所有的浏覽器 – 除了火狐,它在keypress事務中的keyCode傳回值為0。

四.W3C與IE

在标準的DOM事件中,event對象包含與建立它的特定事件有關的屬性和方法。觸發的事件類型不一樣,可用的屬性和方法也不一樣。

W3C中event對象的屬性和方法

屬性/方法 類型 讀/寫 說明
bubbles Boolean 隻讀 表明事件是否冒泡
cancelable Boolean 隻讀 表明是否可以取消事件的預設行為
currentTarget Element 隻讀 其事件處理程式目前正在處理事件的那個元素
detail Integer 隻讀 與事件相關的細節資訊
eventPhase Integer 隻讀 調用事件處理程式的階段:1表示捕獲階段,2表示“處理目标”,3表示冒泡階段
preventDefault() Function 隻讀 取消事件的預設行為。如果cancelabel是true,則可以使用這個方法
stopPropagation() Function 隻讀 取消事件的進一步捕獲或冒泡。如果bubbles為true,則可以使用這個方法
target Element 隻讀 事件的目标
type String 隻讀 被觸發的事件的類型
view AbstractView 隻讀 與事件關聯的抽象視圖。等同于發生事件的window對象

IE中event對象的屬性

屬性 類型 讀/寫 說明
cancelBubble Boolean 讀/寫 預設值為false,但将其設定為true就可以取消事件冒泡
returnValue Boolean 讀/寫 預設值為true,但将其設定為false就可以取消事件的預設行為
srcElement Element 隻讀 事件的目标
type String 隻讀 被觸發的事件類型

在這裡,我們隻看所有浏覽器都相容的屬性或方法。首先第一個我們了解一下W3C中的target和IE中的srcElement,都表示事件的目标。

function getTarget(evt) {

var e = evt || window.event;

return e.target || e.srcElement;//相容得到事件目标DOM對象

}

document.onclick = function (evt) {

var target = getTarget(evt);

alert(target);

};

事件流

事件流是描述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候,那麼你點選其中一個元素,并不是隻有目前被點選的元素會觸發事件,而層疊在你點選範圍的所有元素都會觸發事件。事件流包括兩種模式:冒泡和捕獲。

事件冒泡,是從裡往外逐個觸發。事件捕獲,是從外往裡逐個觸發。那麼現代的浏覽器預設情況下都是冒泡模型,而捕獲模式則是早期的Netscape預設情況。而現在的浏覽器要使用DOM2級模型的事件綁定機制才能手動定義事件流模式。

document.onclick = function () {

alert('我是document');

};

document.documentElement.onclick = function () {

alert('我是html');

};

document.body.onclick = function () {

alert('我是body');

};

document.getElementById('box').onclick = function () {

alert('我是div');

};

document.getElementsByTagName('input')[0].onclick = function () {

alert('我是input');

};

在阻止冒泡的過程中,W3C和IE采用的不同的方法,那麼我們必須做一下相容。

function stopPro(evt) {

var e = evt || window.event;

window.event ? e.cancelBubble = true : e.stopPropagation(); 

}