發文不易,若轉載傳播,請親註明出處,謝謝! javascript
內容提綱:html
1.事件對象java
2.鼠標事件windows
3.鍵盤事件數組
4.W3C與IE瀏覽器
JavaScript事件的一個重要方面是它們擁有一些相對一致的特色,能夠給你的開發提供更多的強大功能。最方便和強大的就是事件對象,他們能夠幫你處理鼠標事件和鍵盤敲擊方面的狀況,此外還能夠修改通常事件的捕獲/冒泡流的函數。函數
一.事件對象post
事件處理函數的一個標準特性是,以某些方式訪問的事件對象包含有關於當前事件的上下文信息。this
事件處理三部分組成:對象.事件處理函數=函數。例如:單擊文檔任意處。編碼
document.onclick = function () {
alert('Lee');
};
PS:以上程序的名詞解釋:click表示一個事件類型,單擊。onclick表示一個事件處理函數或綁定對象的屬性(或者叫事件監聽器、偵聽器)。document表示一個綁定的對象,用於觸發某個元素區域。function()匿名函數是被執行的函數,用於觸發後執行。
除了用匿名函數的方法做爲被執行的函數,也能夠設置成獨立的函數。
document.onclick = box; //直接賦值函數名便可,無須括號
function box() {
alert('Lee');
}
this關鍵字和上下文
在面向對象知識中咱們知道:在一個對象裏,因爲做用域的關係,this表明着離它最近對象。
代碼片斷1:
var input = document.getElementsByTagName('input')[0]; input.onclick = function () { alert(this.value); //HTMLInputElement,this表示input對象 };
代碼片斷2:
1 window.onload = function () { 2 3 //由於box()函數被onclick綁定了,因此裏面的this表明document 4 5 //document.onclick = box; 6 7 }; 8 9 function box() { 10 11 alert(this); //HTMLDocument,表明是document 12 13 }; 14 15
代碼片斷3:
1 //全局調用 2 3 function box() { 4 5 alert(this); 6 7 }; 8 9 box(); //object Window,全局調用this表明window 10 11
從上面的拆分,咱們並無發現本章的重點:事件對象。那麼事件對象是什麼?它在哪裏呢?當觸發某個事件時,會產生一個事件對象,這個對象包含着全部與事件有關的信息。包括致使事件的元素、事件的類型、以及其它與特定事件相關的信息。
事件對象,咱們通常稱做爲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);
};
注意: window.event這個屬性IE是支持的,Chrome也是支持的,Chrome也是支持W3C的evt。若是說W3C和IE的都支持的話,那麼就已W3C爲準。
二.鼠標事件
鼠標事件是Web上面最經常使用的一類事件,畢竟鼠標仍是最主要的定位設備。那麼經過事件對象能夠獲取到鼠標按鈕信息和屏幕座標獲取等。
1.鼠標按鈕
只有在主鼠標按鈕被單擊時(常規通常是鼠標左鍵)纔會觸發click事件,所以檢測按鈕的信息並非必要的。
但對於mousedown和mouseup事件來講,則在其event對象存在一個button屬性,表示按下或釋放按鈕。
非IE(W3C)中的button屬性
值 |
說明 |
0 |
表示主鼠標按鈕(常規通常是鼠標左鍵) |
1 |
表示中間的鼠標按鈕(鼠標滾輪按鈕) |
2 |
表示次鼠標按鈕(常規通常是鼠標右鍵) |
IE中的button屬性
值 |
說明 |
0 |
表示沒有按下按鈕 |
1 |
表示主鼠標按鈕(常規通常是鼠標左鍵) |
2 |
表示次鼠標按鈕(常規通常是鼠標右鍵) |
3 |
表示同時按下了主、次鼠標按鈕 |
4 |
表示按下了中間的鼠標按鈕 |
5 |
表示同時按下了主鼠標按鈕和中間的鼠標按鈕 |
6 |
表示同時按下了次鼠標按鈕和中間的鼠標按鈕 |
7 |
表示同時按下了三個鼠標按鈕 |
PS:在絕大部分狀況下,咱們最多隻使用主次中三個單擊鍵,IE給出的其餘組合鍵通常沒法使用上。因此,咱們只須要作上這三種兼容便可。
1 function getButton(evt) { //跨瀏覽器左中右鍵單擊相應 2 3 var e = evt || window.event; 4 5 if (evt) { //Chrome瀏覽器支持W3C和IE 6 7 return e.button; //要注意判斷順序 8 9 } else if (window.event) { 10 11 switch(e.button) { 12 13 case 1 : 14 15 return 0; 16 17 case 4 : 18 19 return 1; 20 21 case 2 : 22 23 return 2; 24 25 } 26 27 } 28 29 } 30 31 32 33 document.onmouseup = function (evt) { //調用 34 35 if (getButton(evt) == 0) { 36 37 alert('按下了左鍵!'); 38 39 } else if (getButton(evt) == 1) { 40 41 alert('按下了中鍵!'); 42 43 } else if (getButton(evt) == 2) { 44 45 alert('按下了右鍵!' ); 46 47 } 48 49 };
2.可視區及屏幕座標
事件對象提供了兩組來獲取瀏覽器座標的屬性,一組是頁面可視區左邊,另外一組是屏幕座標。
座標屬性
屬性 |
說明 |
clientX |
可視區X座標,距離左邊框的位置 |
clientY |
可視區Y座標,距離上邊框的位置 |
screenX |
屏幕區X座標,距離左屏幕的位置 |
screenY |
屏幕區Y座標,距離上屏幕的位置 |
1 document.onclick = function (evt) { //點擊位置 2 3 var e = evt || window.event; 4 5 alert(e.clientX + ',' + e.clientY); 6 7 alert(e.screenX + ',' + e.screenY); 8 9 };
3.修改鍵
有時,咱們須要經過鍵盤上的某些鍵來配合鼠標來觸發一些特殊的事件。這些鍵爲:Shfit、Ctrl、Alt和Meat(Windows中就是Windows鍵,蘋果機中是Cmd鍵),它們常常被用來修改鼠標事件和行爲,因此叫修改鍵。
修改鍵屬性
屬性 |
說明 |
shiftKey |
判斷是否按下了Shfit鍵 |
ctrlKey |
判斷是否按下了ctrlKey鍵 |
altKey |
判斷是否按下了alt鍵 |
metaKey |
判斷是否按下了windows鍵,IE不支持 |
1 function getKey(evt) { 2 3 var e = evt || window.event; 4 5 var keys = []; 6 7 8 9 if (e.shiftKey) keys.push('shift'); //給數組添加元素 10 11 if (e.ctrlKey) keys.push('ctrl'); 12 13 if (e.altKey) keys.push('alt'); 14 15 16 17 return keys; 18 19 } 20 21 22 23 document.onclick = function (evt) { 24 25 alert(getKey(evt)); 26 27 };
三.鍵盤事件
用戶在使用鍵盤時會觸發鍵盤事件。「DOM2級事件」最初規定了鍵盤事件,結果又刪除了相應的內容。最終仍是使用最初的鍵盤事件,不過IE9已經率先支持「DOM3」級鍵盤事件。
入門篇知識回顧:
keydown,按下任意鍵,按下的意思就是按下當即觸發;
keyup,是彈起任意鍵,彈起就是按下而後釋放觸發;
keypress,是按下字符鍵,abc,123,標點符號,特殊字符等,shift,ctrl,alt等則不是字符的鍵,所以無效。
1.鍵碼(鍵盤上的任意鍵)
在發生keydown和keyup事件時,event對象的keyCode屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字符集,keyCode屬性的值與ASCII碼中對應小寫字母或數字的編碼相同。字母中大小寫不影響(好比:大寫A和小寫a返回的都是65)。
document.onkeydown = function (evt) {
alert(evt.keyCode); //按任意鍵,獲得相應的keyCode值
};
注意:若是用keypress返回keyCode,發現Firefox瀏覽器把全部字符鍵(注意這兒各瀏覽器針對的都是字符鍵)返回0,可是Chrome,IE支持keypress返回keyCode,並且還支持大小寫。
不一樣的瀏覽器在keydown和keyup事件中,會有一些特殊的狀況:
在Firefox和Opera中,分號鍵時keyCode值爲59,也就是ASCII中分號的編碼;而IE和Safari返回186,即鍵盤中按鍵的鍵碼。
PS:其餘一些特殊狀況因爲瀏覽器版本太老和市場份額過低,這裏不作補充。
2.字符編碼(鍵盤上能夠輸出的字符的鍵)
Firefox、Chrome和Safari的event對象都支持一個charCode屬性,這個屬性只有在發生keypress事件時才包含值,並且這個值是按下的那個鍵所表明字符的ASCII編碼。此時的keyCode一般等於0或者也可能等於所按鍵的編碼。IE和Opera不支持charCode而是在keyCode中保存字符的ASCII編碼。
PS:通常狀況下,咱們無論非字符鍵,基本上處理的都是字符按鍵,因此對字符按鍵作瀏覽器兼容,代碼以下:
1 function getCharCode(evt) { 2 3 var e = evt || window.event; 4 5 if (typeof e.charCode == 'number') { 6 7 return e.charCode; 8 9 } else { 10 11 return e.keyCode; 12 13 } 14 15 }
PS:可使用String.fromCharCode()將ASCII編碼轉換成實際的字符。
document.onkeypress = function (evt) {
alert(String.fromCharCode(getCharCode(evt))); //charCode返回字符編碼
};
下面這些只做爲參考就好,由上面的字符鍵兼容代碼就行了!
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事務
四.W3C與IE
在標準的DOM事件中,event對象包含與建立它的特定事件有關的屬性和方法。觸發的事件類型不同,可用的屬性和方法也不同。
W3C中event對象的屬性和方法
屬性/方法 |
類型 |
讀/寫 |
說明 |
bubbles |
Boolean |
只讀 |
代表事件是否冒泡 |
cancelable |
Boolean |
只讀 |
代表是否能夠取消事件的默認行爲 |
currentTarget |
Element |
只讀 |
其事件處理程序當前正在處理事件的那個元素 |
detail |
Integer |
只讀 |
與事件相關的細節信息 |
eventPhase |
Integer |
只讀 |
調用事件處理程序的階段:1表示捕獲階段,2表示「處理目標」,3表示冒泡階段 |
preventDefault() |
Function |
只讀 |
取消事件的默認行爲。若是cancelable是true,則可使用這個方法 |
stopPropagation() |
Function |
只讀 |
取消事件的進一步捕獲或冒泡。若是bubbles爲true,則可使用這個方法 |
target |
Element |
只讀 |
事件的目標 |
type |
String |
只讀 |
被觸發的事件的類型 |
view |
AbstractView |
只讀 |
與事件關聯的抽象視圖。等同於發生事件的window對象 |
IE中event對象的屬性(因此作兼容就要以IE方法爲準)
屬性 |
類型 |
讀/寫 |
說明 |
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) { //點擊哪裏,就能夠獲得哪裏的DOM元素對象
var target = getTarget(evt);
alert(target);
};
事件流
事件流是描述的從頁面接受事件的順序,當幾個都具備同一事件(如點擊事件)的元素層疊在一塊兒的時候,那麼你點擊其中一個元素,並非只有當前被點擊的元素會觸發事件,而層疊在你點擊範圍的全部元素都會觸發事件。事件流包括兩種模式:冒泡和捕獲。
事件冒泡,是從裏往外逐個觸發。事件捕獲,是從外往裏逐個觸發。那麼現代的瀏覽器默認狀況下都是冒泡模型,而捕獲模式則是早期的Netscape默認狀況。而如今的瀏覽器要使用DOM2級模型的事件綁定機制才能手動定義事件流模式。
小示例:
html代碼部分:
1 <body> 2 3 <div id = "box" style= "width:100px;height:100px;background:red"> 4 5 <input type="button" value="按鈕" /> 6 7 </div> 8 9 </body>
JS代碼部分:
1 window.onload = function () { 2 3 document.onclick = function () { 4 5 alert('document'); 6 7 }; 8 9 document.documentElement.onclick = function () { 10 11 alert('html'); 12 13 }; 14 15 document.body.onclick = function () { 16 17 alert('body'); 18 19 }; 20 21 document.getElementById('box').onclick = function () { 22 23 alert('div'); 24 25 }; 26 27 document.getElementsByTagName('input')[0].onclick = function (evt) { 28 29 alert('input'); 30 31 setStop(evt); 32 33 }; 34 35 }; 36 37 38 39 function setStop(evt) { 40 41 var e = evt || window.event; 42 43 (typeof e.stopPropagation == 'function') ? e.stopPropagation() : e.cancelBubble = true; 44 45 //或者:window.event ? e.cancelBubble = true : e.stopPropagation(); 46 47 }
戒浮戒躁,鍥而不捨!
for my lover and
thank you, MR Lee!
發文不易,若轉載傳播,請親註明出處,謝謝!