Event事件

客戶端JavaScript程序採用了異步事件驅動編程模型。
 
1、相關術語
 
事件就是Web瀏覽器通知應用程序發生了什麼事情。
 
事件類型(event type)是一個用來講明發生什麼類型事件的字符串。例如,「mousemove」表示用戶移動鼠標,「keydown」表示鍵盤上某個鍵被按下等等。
事件目標(event target)是發生的事件與之相關的對象。當講事件時,我必須同時指明類型和目標。好比:window上的load事件或<button>元素的click事件。
在客戶端JavaScript應用程序中,Window、Document和Element對象是最多見的事件目標。
事件處理程序(event handler)或 事件監聽程序(event listener)是處理或響應事件的函數。
事件對象(event object)是與特定事件相關且包含有關該事件詳細信息的對象。事件對象做爲參數傳遞給事件處理程序函數(不包括IE8及以前版本,在這些瀏覽器中有時僅能經過全局變量event才能獲得)。全部的事件對象都用來指定事件類型的type屬性和指定事件目標的target屬性。(在IE8及以前的版本中用srcElement而非target)
事件傳播(event propagation)是瀏覽器決定哪一個對象觸發其事件處理程序的過程。當文檔元素上發生某個類型的事件時,它們會在文檔樹上向上傳播或「 冒泡「(bubble)。
事件傳播的另外一種方式: 事件捕獲(event capturing):在容器元素上註冊的特定處理程序有機會在事件傳播到真實目標以前捕獲它。
 
2、Event事件
 
10.1註冊事件處理程序
 
註冊事件處理程序有兩種基本方式:
(1)一種是給事件目標對象或文檔元素設置屬性。
按照約定,事件處理程序屬性的名字由「on」後面跟着事件名組成:onclick、onchange等。這些屬性名是區分大小寫的,全部都是小寫,即便是事件類型是由多個詞組成的(好比「readystatechange」)。

<div onclick="alert(1);"></div>javascript

 

window.onload=function(){}html

:儘可能少用內聯事件
 
事件處理程序屬性的缺點是其設計都是圍繞着假設每一個事件目標對於每種事件類型將最多隻有一個處理程序。
 
(2)另外一種是經過 addEventListener()
window對象、Document對象和全部的文檔元素(Element)都定義了一個名爲addEventListener()方法,使用這個方法能夠爲事件目標註冊事件處理程序。

target.addEventListener(type, listener[, useCapture]);
java

addEventListener方法接受三個參數。

type:事件名稱(事件類型),字符串,大小寫不敏感。 listener:監聽函數。事件發生時,會調用該監聽函數。 useCapture:布爾值,表示監聽函數是否在捕獲階段(capture)觸發,默認爲false(監聽函數只在冒泡階段被觸發)。老式瀏覽器規定該參數必寫,較新版本的瀏覽器容許該參數可選。爲了保持兼容,建議老是寫上該參數。
編程

使用addEventListener()方法時,事件類型不該包括前綴「on」,好比:「onclick」改爲「click」等。

addEventListener('click',listener,false);canvas

注意:調用addEventListener()並不會影響onclick屬性的值。

<button id="mybutton">點擊</button>數組

 

var v = document.getElementById('mybutton');瀏覽器

v.onclick = function() {alert('1');}緩存

v.addEventListener('click',function(){alert('2');},false);服務器

上面的代碼中,單擊按鈕會產生兩個alert()對話框。
 
能經過屢次調用addEventListener()方法爲同一個對象註冊同一事件類型的多個處理程序函數。全部該事件類型的註冊處理程序都會按照註冊的順序調用。使用相同的參數在同一個對象上屢次調用addEventListener()是沒用的,處理程序仍然只註冊一次,同時重複調用也不會改變調用處理程序的順序(也就是說,若是爲同一個事件屢次添加同一個監聽函數,函數只會執行一次,多餘的添加將自動刪除)。
 
相對addEventListener()的是 removeEventListener() 方法。
removeEventListener方法的參數,與addEventListener方法徹底一致。它的第一個參數「事件類型」,也是大小寫不敏感。
 
注意:removeEventListener()方法的事件處理程序函數必須是函數名。
 
dispatchEvent()
dispatchEvent方法在當前節點上觸發指定事件,從而觸發監聽函數的執行。該方法返回一個布爾值,只要有一個監聽函數調用了Event.preventDefault(),則返回值爲false,不然爲true。

target.dispatchEvent(event)
session

dispatchEvent方法的參數是一個Event對象的實例。
 
在IE上
IE9之前的IE不支持addEventListener()和removeEventListener()。不過咱們可使用相似的方法attachEvent()和detachEvent();
 
attachEvent()detachEvent()方法的工做原理與addEventListener()和removeEventListener()相似,但有所區別:
  • 由於IE事件模型不支持事件捕獲,因此attachEvent()和detachEvent()只有兩個參數:事件類型和處理程序函數
  • IE方法的第一個參數使用了帶「on」前綴的事件處理程序屬性名。例如:當給addEventListener()傳遞「click」時,要給attachEvent()傳遞「onclick」
  • attachEvent()容許相同的事件處理程序函數註冊屢次。當特定的事件類型發生時,註冊函數的調用次數和註冊次數同樣。
 
下面的代碼中能夠兼容ie瀏覽器:

//添加事件處理器

var addEvent = function(element, type, handler, useCapture) {   

  if(element.addEventListener) {   

    element.addEventListener(type, handler, useCapture ? true : false);   

  } else if(element.attachEvent) {   

    element.attachEvent('on' + type, handler);   

  } else if(element != window){   

    element['on' + type] = handler;   

  }   

};

//移除某個事件處理器

var removeEvent = function(element, type, handler, useCapture) {   

  if(element.removeEventListener) {   

    element.removeEventListener(type, handler, useCapture ? true : false);   } else if(element.detachEvent) {

     element.detachEvent('on' + type, handler);   

  } else if(element != window){   

    element['on' + type] = null;   

  }   

};

 
10.2 事件處理程序的調用
一旦註冊了事件處理程序,瀏覽器就會在指定對象上發生指定類型事件時自動調用它。
 
10.2.1 事件處理程序的參數
一般調用事件處理程序時把事件對象(event)做爲它們的一個參數。事件對象的屬性提供了有關事件的詳細信息。例如,type屬性指定了發生的事件類型。
 
在IE8及之前的版本中,經過設置屬性註冊事件處理程序,當調用它們時並未傳遞事件對象。取而代之,須要經過全局對象window.event來得到事件對象。
下面的代碼就是考慮了兼容性:

function handler(event){

  event = event || window.event;

}

 
10.2.2 事件處理程序的運行環境
當經過設置屬性註冊事件處理程序時,看起來就好像是在文檔元素上定義了新方法:

e.onclick=function(){}

事件處理程序在事件目標上定義,因此它們做爲這個對象的方法來調用。也就是說,在事件處理程序內,this關鍵字指向事件目標。
 

10.2.3 事件處理程序的做用域

事件處理程序在其定義的做用域而非調用時的做用域中執行,而且它們能存取那個做用域中的任何一個本地變量。

 

10.2.4 事件處理程序的返回值

經過設置對象屬性或HTML屬性註冊事件處理程序的返回值有時是很是有意義的。一般狀況下,返回值false就是告訴瀏覽器不要執行這個事件相關的默認操做。好比,表單提交按鈕的onclick事件處理程序能返回false阻止瀏覽器提交表單。

v.onclick = function() {

  return false;

}

理解事件處理程序的返回值只對經過屬性註冊的處理程序纔有意義。

 

10.2.5 調用順序

文檔元素或其餘對象能夠指定事件類型註冊多個事件處理程序。當適當的事件發生時,瀏覽器必須按照下面的規則調用全部的事件處理程序:

  • 經過設置對象屬性或HTML屬性註冊的處理程序一直優先調用。
  • 使用addEventListener()註冊的處理程序按照它們的註冊順序調用。
  • 使用attachEvent()註冊的處理程序可能按照任何順序調用,因此代碼不該該依賴於調用順序。

 

10.2.6 事件傳播

當事件目標是Window對象或其餘一些單獨對象(好比XMLHttpRequest)時,瀏覽器會簡單的經過調用對象上適當的處理程序響應事件。

 

在調用在目標元素上註冊的事件處理函數後,大部分事件會「冒泡」到DOM樹根。

 

 發生在文檔元素上的大部分事件都會冒泡,但有些例外,好比focus、blur和scroll事件。文檔元素上的load事件會冒泡,但它會在Document對象上中止冒泡而不會傳播到Window對象。只有當整個文檔都加載完畢時纔會觸發window對象的load事件。

 

當事件目標是文檔或文檔元素時,它會在不一樣的DOM節點之間傳播(propagation)。

分爲三個階段:

  • 捕獲階段(capture phase):從window對象傳導到目標對象。(window--document--....--目標對象)
  • 目標階段(target phase):目標對象自己的事件處理程序調用。
  • 冒泡階段(bubbling phase):從目標對象傳導回window對象。(目標對象--父元素--....--document--window)

 

事件代理(事件委託)

基於事件會在冒泡階段向上傳播到父節點,咱們能夠將子節點的監聽事件定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件。這種方法叫作事件的代理(delegation)。

<div id="div">   

  <div id="item">123</div>   

</div>

 

document.getElementById('div').addEventListener('click', function(e) {   

  var target = e.target;   

  if(target.getAttribute('id').toLowerCase() == 'item') {   

    alert(1);   

  }   

});

若是使用事件代理,之後插入的新節點仍然能夠監聽的到。

 

若是使用JQuery,咱們要爲新增節點添加事件,除了在新增事件後添加事件外,還能夠用下面的代碼:

$(document).on('click','div',function(){})

這種方式其實就是使用了事件代理。

 

10.2.7 事件取消

用屬性註冊的世界處理程序的返回值能用於取消事件的瀏覽器默認操做。在支持addEventListener()的瀏覽器中,也能經過調用事件對象的preventDefault()方法取消事件的默認操做。

在IE9以前的IE中,能夠經過設置事件對象的returnValue屬性爲false來達到一樣的效果。

function cancelHandler(event){

  var event = event || window.event;

  if(event.preventDefault) {event.preventDefault();}  //標準

  if(event.returnValue) { event.returnValue = false;}  // IE

  return false; //用於處理使用對象屬性註冊的處理程序

}

 

Event對象提供了一個屬性defaultPrevented,返回一個布爾值,默認false,表示該事件是否調用過preventDefault方法。

 

取消事件傳播

在支持addEventListener()的瀏覽器中,能夠調用事件對象的一個stopPropagation()方法以阻止事件的繼續傳播。

e.stopPropagation()

//IE

e.cancelBubble = true;

 

在Event對象上還有一個方法stopImmediatePropagation(),阻止同一個事件的其餘監聽函數被調用。也就是說,若是同一個節點對於同一個事件指定了多個監聽函數,這些函數會根據添加的順序依次調用。只要其中有一個監聽函數調用了stopImmediatePropagation方法,其餘的監聽函數就不會再執行了。

e.addEventListener('click',function(event){

  event.stopImmediatePropagation();

});

e.addEventListener('click',function(event){   

  //不會觸發

});

 

10.3 文檔事件

(1)beforeunload事件、unload事件、load事件、error事件、pageshow事件、pagehide事件

 

beforeunload

當瀏覽器將要跳轉到新頁面時觸發這個事件。若是事件處理程序返回一個字符串,那麼它將出如今詢問用戶是否想離開當前頁面的標準對話框中。

window.addEventListener('beforeunload',function(e){

  var message = '你確認要離開嗎!';

  e.returnValue = message;

  return message

});

 

unload

unload事件在窗口關閉或者document對象將要卸載時觸發,發生在window、body、frameset等對象上面。它的觸發順序排在beforeunload、pagehide事件後面。unload事件只在頁面沒有被瀏覽器緩存時纔會觸發,換言之,若是經過按下「前進/後退」致使頁面卸載,並不會觸發unload事件。

 

load、error

load事件直到文檔和全部圖片加載完畢時纔會觸發,error事件在頁面加載失敗時觸發。注意,頁面從瀏覽器緩存加載,並不會觸發load事件。

 

pageshow、pagehide

默認狀況下,瀏覽器會在當前會話(session)緩存頁面,當用戶點擊「前進/後退」按鈕時,瀏覽器就會從緩存中加載頁面。

 

pageshow事件在頁面加載時觸發,包括第一次加載和從緩存加載兩種狀況。若是要指定頁面每次加載(無論是否是從瀏覽器緩存)時都運行的代碼,能夠放在這個事件的監聽函數。

pageshow事件有一個persisted屬性,返回一個布爾值。頁面第一次加載時,這個屬性是false;當頁面從緩存加載時,這個屬性是true。

 

pagehide事件與pageshow事件相似,當用戶經過「前進/後退」按鈕,離開當前頁面時觸發。

pagehide事件的event對象有一個persisted屬性,將這個屬性設爲true,就表示頁面要保存在緩存中;設爲false,表示網頁不保存在緩存中,這時若是設置了unload事件的監聽函數,該函數將在pagehide事件後當即運行。

 

(2)DOMContentLoaded事件、readystatechange事件

DOMContentLoaded事件:當文檔加載解析完畢且全部延遲(deferred)腳本(圖片未加載完畢)都執行完畢時會觸發,此時圖片和異步(async)腳本可能依舊在加載,可是文檔已經爲操做準備就緒了。也就是說,這個事件,發生在load事件以前。

document.addEventListener('DOMContentLoaded',handler,false);

 

readystatechange事件:document.readyState屬性會隨着文檔加載過程而變,而每次狀態改變,Document對象上的readystatechange事件都會觸發。

document.onreadystatechange = function() {

  if(document.readyState == 'complete'){

    

  }

}

 

(3)scroll事件、resize事件

scroll事件在文檔或文檔元素滾動時觸發,主要出如今用戶拖動滾動條。

resize事件在改變瀏覽器窗口大小時觸發,發生在window、body、frameset對象上面。

 

(4)hashchange事件、popstate事件

hashchange事件在URL的hash部分(即#號後面的部分,包括#號)發生變化時觸發。若是老式瀏覽器不支持該屬性,能夠經過按期檢查location.hash屬性,模擬該事件。

 

popstate事件在瀏覽器的history對象的當前記錄發生顯式切換時觸發。注意,調用history.pushState()或history.replaceState(),並不會觸發popstate事件。該事件只在用戶在history記錄之間顯式切換時觸發,好比鼠標點擊「後退/前進」按鈕,或者在腳本中調用history.back()、history.forward()、history.go()時觸發。

 

(5)cut事件、copy事件、paste事件

這三個事件屬於文本操做觸發的事件。

cut事件:在將選中的內容從文檔中移除,加入剪貼板後觸發。   

copy事件:在選中的內容加入剪貼板後觸發。   

paste事件:在剪貼板內容被粘貼到文檔後觸發。

這三個事件都有一個clipboardData只讀屬性。該屬性存放剪貼的數據,是一個DataTransfer對象。

 

(6)焦點事件

焦點事件發生在Element節點和document對象上。

focus事件:Element節點得到焦點後觸發,該事件不會冒泡。   

blur事件:Element節點失去焦點後觸發,該事件不會冒泡。   

focusin事件:Element節點將要得到焦點時觸發,發生在focus事件以前。該事件會冒泡。Firefox不支持該事件。   

focusout事件:Element節點將要失去焦點時觸發,發生在blur事件以前。該事件會冒泡。Firefox不支持該事件。

這四個事件的事件對象,帶有target屬性(返回事件的目標節點)和relatedTarget屬性(返回一個Element節點)。對於focusin事件,relatedTarget屬性表示失去焦點的節點;對於focusout事件,表示將要接受焦點的節點;對於focus和blur事件,該屬性返回null。 

 

因爲focus和blur事件不會冒泡,只能在捕獲階段觸發,因此addEventListener方法的第三個參數須要設爲true。

 

10.4 鼠標事件

(1)click

click事件當用戶在Element節點、document節點、window對象上,單擊鼠標(或者按下回車鍵)時觸發。

 

「鼠標單擊」定義爲,用戶在同一個位置完成一次mousedown動做和mouseup動做。它們的觸發順序是:mousedown首先觸發,mouseup接着觸發,click最後觸發。

 

(2)contextmenu

contextmenu事件在一個節點上點擊鼠標右鍵時觸發,或者按下「上下文菜單」鍵時觸發。

 

能夠經過下面的方式阻止「上下文菜單」的出現:

document.oncontextmenu=function(){        

  return false;    

}

 

(3)dblclick

dblclick事件當用戶在element、document、window對象上,雙擊鼠標時觸發。該事件會在mousedown、mouseup、click以後觸發。

 

(4)mousedown、mouseup

mouseup事件在釋放按下的鼠標鍵時觸發。 

mousedown事件在按下鼠標鍵時觸發。

 

(5)mousemove

mousemove事件當鼠標在一個節點內部移動時觸發。當鼠標持續移動時,該事件會連續觸發。爲了不性能問題,建議對該事件的監聽函數作一些限定,好比限定一段時間內只能運行一次代碼。

 

(6)mouseover、mouseenter

mouseover事件和mouseenter事件,都是鼠標進入一個節點時觸發。 

 

二者的區別是,mouseenter事件只觸發一次,而只要鼠標在節點內部移動,mouseover事件會在子節點上觸發屢次。

 

(7)mouseout、mouseleave

mouseout事件和mouseleave事件,都是鼠標離開一個節點時觸發。

 

除了「mouseenter」和「mouseleave」外的全部鼠標事件都能冒泡。連接和提交按鈕上的click事件都有默認操做且可以阻止。能夠取消上下文菜單事件來阻止顯示上下文菜單。

 

傳遞給鼠標事件處理程序的事件對象有clientX和clientY屬性,它們指定了鼠標指針相對於包含窗口的座標。加入窗口的滾動偏移量能夠把鼠標位置轉換成文檔座標。

 

MouseEvent對象的屬性

 

(1)button、buttons

button屬性指定當事件發生時哪一個鼠標按鍵按下。

-1:沒有按下鍵。 

0:按下主鍵(一般是左鍵)。 

1:按下輔助鍵(一般是中鍵或者滾輪鍵)。 

2:按下次鍵(一般是右鍵)。

buttons屬性返回一個3個比特位的值,表示同時按下了哪些鍵。它用來處理同時按下多個鼠標鍵的狀況。

1:二進制爲001,表示按下左鍵。  

2:二進制爲010,表示按下右鍵。  

4:二進制爲100,表示按下中鍵或滾輪鍵。

同時按下多個鍵的時候,每一個按下的鍵對應的比特位都會有值。好比,同時按下左鍵和右鍵,會返回3(二進制爲011)。

 

(2)clientX,clientY 

clientX屬性返回鼠標位置相對於瀏覽器窗口左上角的水平座標,單位爲像素,與頁面是否橫向滾動無關。 

clientY屬性返回鼠標位置相對於瀏覽器窗口左上角的垂直座標,單位爲像素,與頁面是否縱向滾動無關。

 

(3)movementX,movementY 

movementX屬性返回一個水平位移,單位爲像素,表示當前位置與上一個mousemove事件之間的水平距離。在數值上,等於currentEvent.movementX = currentEvent.screenX - previousEvent.screenX。 

movementY屬性返回一個垂直位移,單位爲像素,表示當前位置與上一個mousemove事件之間的垂直距離。在數值上,等於currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。

 

(4)screenX,screenY 

screenX屬性返回鼠標位置相對於屏幕左上角的水平座標,單位爲像素。 

screenY屬性返回鼠標位置相對於屏幕左上角的垂直座標,單位爲像素。

 

(7)pageX、pageY

 pageX和pageY分別是觸點相對HTML文檔左邊沿的X座標和觸點相對HTML文檔上邊沿的Y座標。只讀屬性。

 當存在滾動的偏移時,pageX包含了水平滾動的偏移,pageY包含了垂直滾動的偏移。

 

(6)relatedTarget

relatedTarget屬性返回事件的次要相關節點。對於那些沒有次要相關節點的事件,該屬性返回null。

 

10.5 鼠標滾輪事件

全部的現代瀏覽器都支持鼠標滾輪,並在用戶滾動滾輪時觸發事件。瀏覽器一般使用鼠標滾輪滾動或縮放文檔,但能夠經過取消mousewheel事件來阻止這些默認操做。

 

全部瀏覽器都支持「mousewheel」事件,但Firefox使用「DOMMouseScroll」事件。

 

傳遞給「mousewheel」處理程序的事件對象有wheelDelta屬性,其指定用戶滾動滾輪有多遠(根據這個判斷滾動方向)。

 

遠離用戶方向的一次鼠標滾輪「單擊」的wheelDelta值一般是120,而接近用戶方向的一次「單擊」的值是-120。返回的老是120的倍數(120代表mouse向上滾動,-120代表鼠標向下滾動)

 

在Safari和Chrome中,爲了支持使用二維軌跡球而非一維滾輪的Apple鼠標,除了wheelDelta屬性外,事件對象還有wheelDeltaX和wheelDeltaY,而wheelDelta和wheelDeltaY的值一直相同。

 

而在Firefox中,傳遞給「DOMMouseScroll」的屬性是detail。不過, detail屬性值的縮放比率和正負符號不一樣wheelDelta,detail值乘以-40和wheelDelta值相等。記錄其滾動距離的是「detail」屬性,它返回的是3的倍數(3代表mouse向下滾動,-3代表mouse向上滾動)。

window.onmousewheel = document.onmousewheel = scrollWheel;

 

function scrollWheel(e){

  e = e || window.event;   

  if(e.wheelDelta) { //判斷瀏覽器IE,谷歌滑輪事件                

    if(e.wheelDelta > 0) {   

      //當滑輪向上滾動時       

    } else if(e.wheelDelta < 0) { 

      //當滑輪向下滾動時        

    };   

  } else if(e.detail) { //Firefox滑輪事件   

    if(e.detail < 0) { 

      //當滑輪向上滾動時      

    } else if(e.detail > 0) { 

      //當滑輪向下滾動時          

    };   

  };

}

 

10.6 鍵盤事件

鍵盤事件用來描述鍵盤行爲,主要有keydown、keypress、keyup三個事件。  

keydown:按下鍵盤時觸發該事件。  

keypress:只要按下的鍵並不是Ctrl、Alt、Shift和Meta,就接着觸發keypress事件。 

keyup:鬆開鍵盤時觸發該事件。

textinput

任什麼時候候,只要用戶輸入文本都會觸發。在Webkit瀏覽器中支持「textInput」事件。

 

事件對象屬性data(保存輸入文本),inputMethod屬性(用於指定輸入源)

 

注意:keypress和textinput事件是在新輸入的文本真正插入到聚焦的文檔元素前觸發的。

 

若是用戶一直按鍵不鬆開,就會重複觸發keydown、keypress,直到用戶鬆開纔會觸發keyup。

 

屬性

keycode

指定了輸入字符的編碼。在Firefox中使用的是charCode屬性。

 

altKey,ctrlKey,metaKey,shiftKey

altKey、ctrlKey、metaKey和shiftKey屬性指定了當事件發生時是否有各類鍵盤輔助鍵按下。

altKey屬性:alt鍵  

ctrlKey屬性:key鍵  

metaKey屬性:Meta鍵(Mac鍵盤是一個四瓣的小花,Windows鍵盤是Windows鍵)  

shiftKey屬性:Shift鍵

 

key,charCode key屬性返回一個字符串,表示按下的鍵名。若是同時按下一個控制鍵和一個符號鍵,則返回符號鍵的鍵名。好比,按下Ctrl+a,則返回a。若是沒法識別鍵名,則返回字符串Unidentified。 

 

主要功能鍵的鍵名(不一樣的瀏覽器可能有差別):Backspace,Tab,Enter,Shift,Control,Alt,CapsLock,CapsLock,Esc,Spacebar,PageUp,PageDown,End,Home,Left,Right,Up,Down,PrintScreen,Insert,Del,Win,F1~F12,NumLock,Scroll等。 

 

charCode屬性返回一個數值,表示keypress事件按鍵的Unicode值,keydown和keyup事件不提供這個屬性。注意,該屬性已經從標準移除,雖然瀏覽器還支持,但應該儘可能不使用。

 

String.fromCharCode()

一個keypress事件表示輸入的單個字符。事件對象以數字Unicode編碼的形式指定字符,因此必須用String.fromChatCode()把它轉換成字符串。

 

10.7 表單事件

(1)input、propertychange

檢測文本輸入元素的value屬性改變,這兩個事件是在新輸入的文本真正插入到聚焦的文檔元素前觸發的。

 

通常用在<inupt>和<textarea>裏,不過,當將contenteditable屬性設置爲true時,只要值變化,也會觸發這兩個事件。

 

(2)change

當<input>、<select>和<textarea>的值發生變化時都會觸發change事件。只有所有修改完成時它纔會觸發,這也是它和input事件的區別。

具體分下面幾種狀況:  

激活單選框(radio)或複選框(checkbox)時觸發。 

用戶提交時觸發。好比,從下列列表(select)完成選擇,在日期或文件輸入框完成選擇。 

當文本框或textarea元素的值發生改變,而且喪失焦點時觸發。

 

(3)select

當<input>和<textarea>中選中文本時觸發select事件。

 

(4)reset、submit

這兩個事件是發生在表單對象上,而不是發生在表單的成員上。  

 

reset事件:當表單重置(全部表單成員的值變回默認值)時觸發。  

submit事件:當表單數據向服務器提交時觸發。

 

注意:submit事件的發生對象是form元素,而不是button元素(即便它的類型是submit),由於提交的是表單,而不是按鈕。

 

10.8  觸控事件

觸控事件提供了響應用戶對觸摸屏或觸摸板上操做的能力。

 

觸控API提供了下面三個接口

TouchEvent:表明當觸摸行爲在平面上發生變化時發生的事件

Touch:表明用戶與觸摸屏幕間的一個接觸點

TouchList:表明一系列的Touch;通常在用戶多個手指同時解除屏幕時使用

 

10.8.1 TouchEvent

TouchEvent是一類描述手指在觸摸平面的狀態變化的事件。

 

(1)觸摸事件的類型

touchstart:用戶接觸觸摸屏時觸發,它的target屬性返回發生觸摸的Element節點。   

 

touchend:用戶再也不接觸觸摸屏時(或者移出屏幕邊緣時)觸發,它的target屬性與touchstart事件的target屬性是一致的,它的changedTouches屬性返回一個TouchList對象,包含全部再也不觸摸的觸摸點(Touch對象)。   

 

touchmove:用戶移動觸摸點時觸發,它的target屬性與touchstart事件的target屬性一致。若是觸摸的半徑、角度、力度發生變化,也會觸發該事件。   

 

touchcancel:觸摸點取消時觸發,好比在觸摸區域跳出一個彈出框窗口(modal window)、觸摸點離開了文檔區域(進入瀏覽器菜單欄區域)、用戶放置更多的觸摸點(自動取消早先的觸摸點)。

 

touchenter:當觸點進去某個elemen時觸發。沒有冒泡過程。

 

touchleave:當觸點離開某個element時觸發。沒有冒泡過程。

 

(2)TouchEvent的屬性

鍵盤屬性

如下屬性都爲只讀屬性,返回一個布爾值,表示觸摸的同時,是否按下某個鍵。  

altKey 是否按下alt鍵 

ctrlKey 是否按下ctrl鍵 

metaKey 是否按下meta鍵 

shiftKey 是否按下shift鍵

 

changedTouches

返回一個TouchList對象,包含了表明全部從上一次觸摸事件到這次事件過程當中,狀態發生了改變的觸點的Touch對象。只讀屬性。

 

targetTouches

返回一個TouchList對象,包含了全部當前接觸觸摸平面的觸點的Touch對象(也能夠說是處於活動狀態的觸點的Touch對象)。只讀屬性。

 

touches

返回一個TouchList對象,包含了全部當前接觸觸摸平面的觸點的Touch對象。只讀屬性。

 

type

這次觸摸事件的類型。

 

target

這次觸摸事件的目標元素(element)。這個目標元素對應 TouchEvent.changedTouches 中的觸點的起始元素。

 

10.8.2 Touch

Touch對象表示在觸控設備上的觸控點。一般是指手指或觸控筆在觸屏設備上的操做。

 

每一個Touch對象表明一個觸點,每一個觸點由其位置、大小、形狀、壓力大小和目標element描述。

 

(1)Touch屬性

如下屬性描述了用戶的觸摸行爲

identifier

此Touch對象的惟一標識符。一次觸摸動做在平面上移動的整個過程當中,該標識符不變,能夠根據它來判斷跟蹤是否在同一次觸摸過程。只讀屬性。

 

screenX、screenY

screenX和screenY分別是觸點相對屏幕左邊沿的X座標和觸點相對屏幕上邊沿的Y座標。只讀屬性。

 

clientX、clientY

clientX和clientY分別是觸點相對於可視區左邊沿的X座標和觸點相對可視區上邊沿的Y座標。兩個屬性都不包括任何滾動偏移。只讀屬性。

 

pageX、pageY

pageX和pageY分別是觸點相對HTML文檔左邊沿的X座標和觸點相對HTML文檔上邊沿的Y座標。只讀屬性。

當存在滾動的偏移時,pageX包含了水平滾動的偏移,pageY包含了垂直滾動的偏移。

 

radiusX、radiusY、rotationAngle

radiusX:可以包圍用戶和觸摸平面的接觸面的最小橢圓的水平軸(X軸)半徑. 這個值的單位和 screenX 相同。只讀屬性。

 

radiusY:可以包圍用戶和觸摸平面的接觸面的最小橢圓的垂直軸(Y軸)半徑. 這個值的單位和 screenY 相同。只讀屬性。

 

rotationAngle:由radiusX 和 radiusY 描述的正方向的橢圓,須要經過順時針旋轉這個角度值,才能最精確地覆蓋住用戶和觸摸平面的接觸面,單位爲度數,在0到90度之間。只讀屬性。

 

force

手指擠壓觸摸平面的壓力大小, 從0.0(沒有壓力)到1.0(最大壓力)的浮點數. 只讀屬性.

 

target

當這個觸點最開始被跟蹤時(在 touchstart 事件中), 觸點位於的HTML元素。也就是觸摸發生時的那個節點。

 

10.8.3 TouchList

一個TouchList表明一個觸摸平面上全部觸點的列表。好比一個用戶用三根手指接觸平面,與之相關的TouchList對於每根手指都會生成一個Touch對象,共計三個。

 

(1)TouchList的屬性

length

返回TouchList中Touch對象的數量,只讀屬性。

 

(2)方法

identifiedTouch()

返回列表中標識符與指定值匹配的第一個Touch對象。

 

item()

返回列表中以指定索引值的Touch對象。也可使用數組的語法:touchlist[index]

 

10.8.4 其餘觸控事件

gesturestart、gestureend

scale、rotation

 

10.9 進度事件

進度事件用來描述一個事件進展的過程。好比XMLHttpRequest對象發出的HTTP請求的過程、<img>、<audio>、<video>、<style>、<link>加載外部資源的過程。下載和上傳都會發生進度事件。

 

進度事件有如下幾種:

abort事件:當進度事件被停止時觸發。若是發生錯誤,致使進程停止,不會觸發該事件。   

error事件:因爲錯誤致使資源沒法加載時觸發。   

load事件:進度成功結束時觸發。   

loadstart事件:進度開始時觸發。   

loadend事件:進度中止時觸發,發生順序排在error事件\abort事件\load事件後面。   

progress事件:當操做處於進度之中,由傳輸的數據塊不斷觸發。   

timeout事件:進度超過限時觸發。

 

10.11 拖放事件

拖放(Drag-and-Drop,DnD)是在「拖放源(drag source)」和「拖放目標(drop target)」之間傳輸數據的用戶界面。

 

拖拉的對象有好幾種,包括Element節點、圖片、連接、選中的文字等等。在HTML網頁中,除了Element節點默認不能夠拖拉,其餘(圖片、連接、選中的文字)都是能夠直接拖拉的。爲了讓Element節點可拖拉,能夠將該節點的draggable屬性設爲true。  

<div draggable="true"> 此區域可拖拉 </div>

 draggable屬性可用於任何Element節點,可是圖片(img元素)和連接(a元素)不加這個屬性,就能夠拖拉。對於它們,用到這個屬性的時候,每每是將其設爲false,防止拖拉。

 

注意:一旦某個Element節點的draggable屬性設爲true,就沒法再用鼠標選中該節點內部的文字或子節點了。

 

10.11.1 拖放事件:

dragstart:當一個元素開始被拖拽的時候觸發。用戶拖拽的元素須要附加dragstart事件。在這個事件中,監聽器將設置與此次拖拽相關的信息,例如拖動的數據和圖像。

 

dragenter:當拖拽中的鼠標第一次進入一個元素的時候觸發。這個事件的監聽器須要指明是否容許在這個區域釋放鼠標。若是沒有設置監聽器,或者監聽器沒有進行操做,則默認不容許釋放。當你想要經過相似高亮或插入標記等方式來告知用戶此處能夠釋放,你將須要監聽這個事件。

 

dragover:當拖拽中的鼠標移動通過一個元素的時候觸發。大多數時候,監聽過程發生的操做與dragenter事件是同樣的。

 

dragleave:當拖拽中的鼠標離開元素時觸發。監聽器須要將做爲可釋放反饋的高亮或插入標記去除。

 

drag:這個事件在拖拽源觸發。即在拖拽操做中觸發dragstart事件的元素。

 

drop:這個事件在拖拽操做結束釋放時於釋放元素上觸發。一個監聽器用來響應接收被拖拽的數據並插入到釋放之地。這個事件只有在須要時才觸發。當用戶取消了拖拽操做時將不觸發,例如按下了Escape(ESC)按鍵,或鼠標在非可釋放目標上釋放了按鍵。

 

dragend:拖拽源在拖拽操做結束將獲得dragend事件對象,無論操做成功與否。

注意點:

  • 拖拉過程只觸發以上這些拖拉事件,儘管鼠標在移動,可是鼠標事件不會觸發。
  • 將文件從操做系統拖拉進瀏覽器,不會觸發dragStart和dragend事件。
  • dragenter和dragover事件的監聽函數,用來指定能夠放下(drop)拖拉的數據。因爲網頁的大部分區域不適合做爲drop的目標節點,因此這兩個事件的默認設置爲當前節點不容許drop。若是想要在目標節點上drop拖拉的數據,首先必須阻止這兩個事件的默認行爲,或者取消這兩個事件。

<div ondragover="return false">  

<div ondragover="event.preventDefault()">

下面是一個例子,將圖片拖放到另外一個div中:

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>  

<img id="drag1" src="f.jpg" draggable="true" ondragstart="drag(event)" > 

 

function allowDrop(ev)   

{    

  ev.preventDefault();   

}    

function drag(ev)   

{    

  ev.dataTransfer.setData("Text",ev.target.id);   

}    

function drop(ev)   

{    

  ev.preventDefault();    

  var data=ev.dataTransfer.getData("Text");    

  ev.target.appendChild(document.getElementById(data));   

 

10.11.2 DataTransfer對象

全部的拖拉事件都有一個dataTransfer屬性,用來保存須要傳遞的數據。返回一個DataTransfer對象。

 

拖拉的數據保存兩方面的數據:數據的種類(又稱格式)和數據的值。數據的種類是一個MIME字符串,好比 text/plain或者image/jpeg,數據的值是一個字符串。通常來講,若是拖拉一段文本,則數據默認就是那段文本;若是拖拉一個連接,則數據默認就是連接的URL。 

 

當拖拉事件開始的時候,能夠提供數據類型和數據值;在拖拉過程當中,經過dragenter和dragover事件的監聽函數,檢查數據類型,以肯定是否容許放下(drop)被拖拉的對象。好比,在只容許放下連接的區域,檢查拖拉的數據類型是否爲text/uri-list。 

 

發生drop事件時,監聽函數取出拖拉的數據,對其進行處理。

 

(1)DataTransfer對象的屬性

dropEffect

dropEffect屬性設置放下(drop)被拖拉節點時的效果,可能的值包括copy(複製被拖拉的節點)、move(移動被拖拉的節點)、link(建立指向被拖拉的節點的連接)、none(沒法放下被拖拉的節點)。設置除此之外的值,都是無效的。

e.dataTransfer.dropEffect = 'copy';

dropEffect屬性通常在dragenter和dragover事件的監聽函數中設置,對於dragstart、drag、dragleave這三個事件,該屬性不起做用。

 

effectAllowed

effectAllowed屬性設置本次拖拉中容許的效果,可能的值包括copy(複製被拖拉的節點)、move(移動被拖拉的節點)、link(建立指向被拖拉節點的連接)、copyLink(容許copy或link)、copyMove(容許copy或move)、linkMove(容許link或move)、all(容許全部效果)、none(沒法放下被拖拉的節點)、uninitialized(默認值,等同於all)。若是某種效果是不容許的,用戶就沒法在目標節點中達成這種效果。

dragstart事件的監聽函數,能夠設置被拖拉節點容許的效果;dragenter和dragover事件的監聽函數,能夠設置目標節點容許的效果。

e.dataTransfer.effectAllowed = 'copy';

 

files 

files屬性是一個FileList對象,包含一組本地文件,能夠用來在拖拉操做中傳送。若是本次拖拉不涉及文件,則屬性爲空的FileList對象。

 

types 

types屬性是一個數組,保存每一次拖拉的數據格式,好比拖拉文件,則格式信息就爲File。

 

(2)DataTransfer對象的方法

setData() 

setData方法用來設置事件所帶有的指定類型的數據。它接受兩個參數,第一個是數據類型,第二個是具體數據。若是指定的類型在現有數據中不存在,則該類型將寫入types屬性;若是已經存在,在該類型的現有數據將被替換。

e.dataTransfer.setData('text/plain','bb');

 

getData() 

getData方法接受一個字符串(表示數據類型)做爲參數,返回事件所帶的指定類型的數據(一般是用setData方法添加的數據)。若是指定類型的數據不存在,則返回空字符串。一般只有drop事件觸發後,才能取出數據。若是取出另外一個域名存放的數據,將會報錯。

 

clearData() 

clearData方法接受一個字符串(表示數據類型)做爲參數,刪除事件所帶的指定類型的數據。若是沒有指定類型,則刪除全部數據。若是指定類型不存在,則原數據不受影響。

e.dataTransfer.clearData('text/plain');

 

setDragImage() 

拖動過程當中(dragstart事件觸發後),瀏覽器會顯示一張圖片跟隨鼠標一塊兒移動,表示被拖動的節點。這張圖片是自動創造的,一般顯示爲被拖動節點的外觀,不須要本身動手設置。setDragImage方法能夠用來自定義這張圖片,它接受三個參數,第一個是img圖片元素或者canvas元素,若是省略或爲null則使用被拖動的節點的外觀,第二個和第三個參數爲鼠標相對於該圖片左上角的橫座標和右座標。

 

10.12 自定義事件

咱們可使用自定義事件

//新建事件實例

var event = new Event('play');

//添加監聽函數

element.addEventListener('play',funciton(e){},false);

//觸發事件

element.dispatchEvent(event);

 

CustomEvent()

Event構造函數只能指定事件名,不能在事件上綁定數據。若是須要在觸發事件的同時,傳入指定的數據,須要使用CustomEvent構造函數生成自定義的事件對象。

var event = new CustomEvent('play',{detail: 'play'});

//添加監聽函數 element.addEventListener('play',handler,false); //觸發事件 element.dispatchEvent(event);

CustomEvent構造函數的第一個參數是事件名稱,第二個參數是一個對象。在上面的代碼中,該對象的detail屬性會綁定在事件對象之上。

funciton handler(e){

  var data = e.detail;

}

 

在IE上,並不支持上面的自定義事件寫法,不過,咱們能夠採用老式寫法:

// 新建Event實例  

var event = document.createEvent('Event');   

// 事件的初始化  

event.initEvent('play', true, true);   

// 加上監聽函數  

document.addEventListener('play', handler, false);   

// 觸發事件  

document.dispatchEvent(event);

(1)document.createEvent() 

document.createEvent方法用來新建指定類型的事件。它所生成的Event實例,能夠傳入dispatchEvent方法。

createEvent方法接受一個字符串做爲參數

 

(2)event.initEvent() 

事件對象的initEvent方法,用來初始化事件對象,還能向事件對象添加屬性。該方法的參數必須是一個使用Document.createEvent()生成的Event實例,並且必須在dispatchEvent方法以前調用。

initEvent方法能夠接受四個參數。

type:事件名稱,格式爲字符串。  

bubbles:事件是否應該冒泡,格式爲布爾值。可使用event.bubbles屬性讀取它的值。  

cancelable:事件是否能被取消,格式爲布爾值。可使用event.cancelable屬性讀取它的值。  

option:爲事件對象指定額外的屬性。

 

 

學習參考資料

書籍:《JavaScript權威指南》

文檔:MDN--觸摸事件

文章:阮一峯,JavaScript標準參考教程--Event對象

著做權歸做者全部。
商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
原文: http://ghmagical.com/article/page/id/nXCnaSLsuyWd © ghmagical.com
相關文章
相關標籤/搜索