事件處理

事件類型(event type)是一個用來講明發生什麼類型事件的字符串。javascript

因爲事件類型只是一個字符串,所以實際上有時會稱之爲事件名字。咱們用這個名字來標識所談論的特定類型的事件。html

事件目標(event target)是發生的事件或與之相關的對象。當講事件時,咱們必須同時指明類型和目標。例如,window上的load事件或button上的click事件java

在客戶端的javascript應用程序中,window、document和element對象是最多見的事件目標。但某些事件是有其餘類型的對象觸發。例如,由XMLHttpRequest對象觸發的readystatechange事件jquery

事件處理程序(event handler)或事件監聽程序(event listener)是處理和響應的函數。應用程序指明事件類型和事件目標,在web瀏覽器中註冊它們的事件處理程序函數,當在特定的目標上發生特定類型的事件時,瀏覽器會調用對應的處理程序。當對象上註冊的事件處理程序被調用時,咱們有時會說瀏覽器觸發)(fire trigger)和派發了事件。web

event object 事件對象是與特定事件相關且包含有關該事件詳細信息的對象。事件對象做爲參數傳遞給事件處理程序函數(不包括ie8及以前版本,在這些瀏覽器中有時僅能經過全局變量event才能獲得),全部的事件對象都有用來指定事件類型的type屬性和指定事件目標的target屬性。)(在IE8及以前版本中用srcElement而非target)。每一個事件類型都爲其相關事件對象定義一組屬性chrome

事件傳播(event propagation)是瀏覽器決定哪一個對象觸發其事件處理程序的過程。對於單個對象的特定事件(好比window對象的load事件),必須是不能傳播的。當文檔元素上發生某個類型的事件時,然而。它們會在文檔樹上向上傳播或冒泡,事件處理程序能經過調用方法或設置事件對象屬性來阻止事件傳播,這樣它就能中止冒泡且將沒法在容器上觸發處理程序。瀏覽器

事件傳播的另一種形式稱爲事件捕獲(event capturing),在容器元素上註冊的特定處理程序網絡

有機會在事件傳播到真實目標以前攔截(捕獲)它。IE8及以前版本不支持事件捕獲,因此不經常使用它,可是,當處理鼠標拖放事件時,捕獲或奪取鼠標事件的能力是必須的dom

一些事件有與之相關的默認操做,當超連接上發生click事件時,瀏覽器的默認操做是按照連接加載頁面,事件處理程序能夠經過返回一個適當的值,調用事件對象的某個方法或者設置事件對象的某個屬性來阻止默認操做的發生。這有時稱爲取消事件。異步

一、表單事件,當提交表單和重置表單時,form元素會分別發生submit和reset事件,當用戶和類按鈕表單元素(包括單選按鈕和複選按鈕)交互時,它們會發生click事件。當用戶經過輸入文字、選擇選項或選擇複選框來改變相應表單元素的狀態時,這些一般維護某種狀態的表單元素會觸發change事件。對於文本輸入域,只有用戶和表單元素完成交互並經過tab鍵或者單擊的方式移動焦點到其餘元素上時纔會觸發change事件 。響應經過鍵盤改變焦點的表單元素在獲得和失去焦點時會分別觸發focus和blur事件

經過事件處理程序能取消submit和reset事件的默認操做,某些click事件也是如此。focus和blur事件不會冒泡,但其餘全部表單事件均可以。ie定義了focusin和focusout事件能夠冒泡,它們能夠永遠替代focus和blur事件。

不管用戶什麼時候輸入文字(經過鍵盤或剪切和粘貼)到textarea和其餘文本輸入表單元素,除ie外的瀏覽器都會觸發input事件。不像change事件,每次文字插入都會觸發input事件,遺憾的是,input事件的事件對象沒有指定輸入文字的內容(textinput事件將會成爲這個事件的有用替代方案。)

window事件

是指事件的發生與瀏覽器自己而非窗口中顯示的任何特定文檔內推相關,可是,這些事件中有一些會和文檔元素上發生的事件同名

load事件,當文檔和其全部外部資源(好比圖片)徹底加載並顯示給用戶時就會觸發它。DOMContentLoaded和readystatechange是load事件的替代方案,當文檔和其元素爲操做準備就緒,但外部資源徹底加載完畢以前,瀏覽器就會盡早觸發它們。

unload事件 和load相對,當用戶離開當前文檔時轉向其餘文檔時會觸發它,unload事件處理程序能夠用於保存用戶的狀態,但它不可能用於取消用戶轉向其餘地方。beforeunload事件和unload相似,但它能提供詢問用戶是否肯定離開當前頁面的機會。若是beforeunload的處理程序返回字符串,那麼在新頁面加載以前,字符串會出如今展現給用戶確認的對話框上,這樣用戶將有機會取消其跳轉而留在當前頁面上。

window對象的onerror屬性有點像事件處理程序,當javascript出錯時會觸發他。可是,它不是真正的事件處理程序,由於它能用不一樣的參數來調用。

想img元素這樣的單個文檔元素也能爲load和error事件註冊處理程序。當外部資源(例如圖片)徹底加載或發生阻止加載的錯誤時就會觸發它們。某些瀏覽器也支持也支持abort事件,當圖片(或其餘網絡資源)由於用戶中止加載進程而致使失敗就會觸發它。

表單元素的focus和blur事件也能用作window事件,當瀏覽器窗口從操做系統中獲得或者失去鍵盤焦點時會觸發它們。

當用戶調整瀏覽器窗口大小或滾動它時會觸發resize和scroll事件,scoll事件也能在任何能夠滾動的文檔元素上觸發,好比那些設置CSS的overflow屬性的元素。傳遞給resize和scroll事件處理程序的事件對象是一個很是普通的Event對象,它沒有指定調整大小或發生滾動的詳細信息屬性。

鼠標事件

當用戶在文檔上移動或單擊鼠標時都會發生鼠標事件。這些事件在鼠標指針所對應的最深嵌套元素上觸發,但它們會冒泡知道文檔最頂層。傳遞給鼠標事件處理的事件對象有屬性集,它們描述了當事件發生時鼠標的位置和按鍵狀態,也指明瞭當時是都有任何輔助建按下。clientX和clientY屬性指定了鼠標在窗口座標中的位置,button和which屬性指定了按下的鼠標鍵是哪一個。當鍵盤輔助鍵按下時,對應的屬性altkey、ctrlKey、metaKey和shiftKey會設置爲true,對於click事件,detail屬性指定了其實單擊、雙擊仍是三擊。

當用戶按下或釋放鼠標按鍵時,會觸發mousedown和mouseup事件。經過註冊mousedown和mouseomove事件處理程序,能夠探測和響應鼠標的拖動。合理的這樣作可以捕獲鼠標事件,甚至當鼠標從開始元素移出時咱們都能持續的接受到mousemove事件。

在mousedown和mouseup事件隊列以後,瀏覽器也會觸發click事件。若是用戶在至關短的時間內連續兩次單擊鼠標按鍵,跟在第二個click事件以後是dbclick事件。當單擊鼠標右鍵時,瀏覽器一般會顯示上下文菜單(context menu)。在顯示菜單以前,它們一般會觸發contextmenu事件,而取消這個事件就能夠阻止菜單的顯示。這個事件也是得到鼠標右擊通知的簡單方法。

當用戶移動鼠標指針從而使它懸停到新元素上時,瀏覽器就會在該元素上觸發mouseover事件。當鼠標移動指針從而使他再也不懸停在某個元素上時,瀏覽器就會在該元素上觸發mouseout事件。對於這些事件,事件對象將有related屬性指明這個過程涉及的其餘元素。mouseover和mouseout事件和這裏介紹的全部鼠標事件同樣會冒泡。正由於如此,IE提供了這些事件的不冒泡版本mouseenter和mouseleave,jquery模擬非IE的瀏覽器中這些事件的支持

當用戶滾動鼠標滾輪時,瀏覽器觸發mousewheel事件(或在firefox中是DOMMouseScroll事件)。傳遞的事件對象屬性指定滾輪轉動的大小和方向。3級DOM事件規範正在標準化一個更通用的多維wheel事件

鍵盤事件

當鍵盤聚焦到web瀏覽器時,用戶每次按下或釋放鍵盤上的按鍵時都會產生事件。不管任何文檔元素得到鍵盤焦點都會觸發鍵盤事件,而且他們會冒泡到Document和window對象。若是沒喲元素得到焦點,能夠直接在文檔上觸發事件。傳遞給鍵盤事件處理程序的事件對象有keyCode字段。它指定按下或釋放的鍵是哪一個,除了keyCode,鍵盤事件對象也有altKey,ctrlKey、metaKey和shiftKey,描述鍵盤輔助建的狀態。

keydown和keyup事件是低級鍵盤事件,不管什麼時候按下或釋放按鍵(甚至是輔助建)都會觸發它們。當keydown事件產生可打印字符時,在keydown和keyup之間會觸發另一個keypress事件。當按下鍵重複產生字符時,在keyup事件以前可能產生keypress。keypress是較高級的文本事件,其事件對象指定產生的字符而非按下的鍵。全部瀏覽器支持keydown、keyup和keypress事件。

dom事件

3級DOM事件規範標準了不冒泡的focusin和focusout事件來取代冒泡的focus和blur事件,標準化了冒泡的mouseenter和mouseleave事件來取代不冒泡的mouseover和mouseout事件

3級dom事件規範中新增內容有經過wheel事件對二維鼠標滾輪提供標準支持,經過textinput事件和傳遞新KeyboardEvent對象做爲參數給keydown、keyup和keypress的處理程序來給文本輸入事件提供更好的支持。

wheel事件的處理程序接收到的事件對象除了全部普通鼠標鼠標事件屬性,還有deltaX、deltaY、deltaZ屬性來報告三個不一樣的鼠標滾軸。大多數鼠標滾輪上是一維或者兩維,並不使用deltaZ。

3級DOM事件規範了keypress事件,但不同意使用它而使用稱爲textinput的新事件。傳遞給textinput事件處理程序的事件對象再也不有難以使用的數字keyCode屬性,而有指定輸入文本字符串的data屬性。textinput事件不是鍵盤特定事件,不管經過鍵盤、剪切和粘貼、拖放等方式,每當發生文本輸入時就會觸發它,規範定義了事件對象的inputMethod屬性和一直表明各類文本輸入種類的常量(鍵盤、粘貼、拖放、手寫、語音識別),safari和chrome使用混合大小的textInput來支持這個事件版本,其事件對象有data屬但沒有inputMethod屬性。

註冊事件處理程序

有兩種基本方式

第一種,給事件目標對象或文檔元素設置屬性。第二種方式,是將事件處理程序傳遞給對象或元素的一個方法,每種技術都有兩個版本。能夠在javascript代碼中設置事件處理程序爲對象屬性,或對於文檔元素,能夠在html中直接設置相應屬性。對於經過方法調用的處理程序註冊,有一個標準方法,命名爲addEventListener,除IE8及之前版本以外,全部瀏覽器都支持這個方式,而ie9以前的IE版本支持的是一個叫attachEvent的不一樣方法。

註冊事件處理程序最簡單的方式就是經過設置事件目標的屬性爲所需事件處理程序函數。事件處理程序屬性的名字由「on」後面跟着事件名組成。全部都是大小寫。

設置HTML標籤屬性爲事件處理程序

若是這樣作,屬性值應該是javascript代碼字符串。這段代碼應該是事件處理程序函數的主體,而非完整的函數聲明。也就是說,HTML事件處理程序代碼不該該用大括號包圍且使用function關鍵字做爲前綴。

<button onclick="alert('thank you');">點擊這裏《/button》

若是HTML事件處理程序屬性包含多條javascript語句,要記住必須使用分號分隔這些語句或斷開屬性值使其跨多行。

某些事件類型一般直接在瀏覽器而非任何特定文檔元素上觸發。在javascipt中,這些事件處理程序在window對象上註冊。

在html中,會把他們放在body標籤上,但瀏覽器會在window對象上註冊它們

在除IE及以前版本外的全部瀏覽器都支持的標準事件模型,任何能成爲事件目標的對象-包括Window對象、Document對象和全部文檔元素--都定義了一個名叫addEventListener的方法。使用相同的參數在同一個對象上屢次調用addEventListener是沒用的,處理程序仍然只註冊一次,同時重複調用也不會改變調用處理程序的順序。

相對addEventListener的是removeEventLister

document.removeEventListener("mouseup",handleMouseUp,true);

attachEvent和detachEvent方法的工做原理與addEventListenner和removeEventListent相似,但有以下例外:

一、由於IE事件模型不支持事件捕獲,因此attachEvent和detachEvent要求只有兩個參數:事件類型和處理程序函數。

二、IE的第一參數使用了帶on前綴的事件處理程序屬性名,而非沒有前綴的事件類型

三、attachEvent容許相同的事件處理程序函數註冊。當特定的事件類型發生時,註冊函數的調用次數和註冊次數同樣

事件處理程序的參數

一般調用事件處理程序時把事件對象做爲他們的一個參數(有一個例外)。事件對象的屬性提供了有關事件的詳細信息,例如,type屬性指定了發生的類型。

在IE8及之前版本中,經過設置屬性註冊處理程序,當調用它們時並未傳遞事件對象,取而代之,須要經過全局對象window.event來得到事件對象

function handler(event){

var event=event||window.event;

}

向使用attachEvent註冊的事件處理程序傳遞事件對象,但它們也能使用window.event,當經過設置HTML屬性註冊事件處理程序時,瀏覽器會把javascript編碼轉換到一個函數中。非IE瀏覽器使用event參數來構造函數,而IE在構造函數時沒有有要求參數。若是在這樣的函數中使用event標識符,那麼引用的正是Window.event.在這兩種狀況下,HTML事件處理程序都能做爲event引用事件對象。

 e.onclick=function(){};

事件處理程序在事件目標上定義,因此它們做爲這個對象的方法來調用。這就是說,在事件處理程序內,this關鍵字指的是事件目標。當使用addEventListener註冊時,調用的處理程序使用事件目標做爲它們的this值。可是,對於attachEvent來說這是不對的:使用attachEvent註冊的處理程序做爲函數調用,它們的this值是全局對象(window)。能夠用以下代碼來解決這個問題:

function addEvent(target,type,handler){
  if(target.addEventListener){
 target.addEventListener(type,handler,fasle);
  }
  else{
    target.attachEvent("on"+type,function(event){
      return handler.call(target,event);
      //把處理程序做爲事件目標的方法調用,傳遞事件對象
    })
    
  }

}

注意使用這個方法註冊的事件處理程序不能刪除,由於傳遞給attchEvent的包裝函數沒有保留下來傳遞給detachEvent。

事件處理程序的返回值

經過設置對象屬性或HTML屬性註冊事件處理程序的返回值有時是很是有意義的。一般狀況下,返回值false就是告訴瀏覽器不要執行這個事件相關的默認操做。例如,表單提交按鈕的onclick事件處理程序能返回false阻止瀏覽器提交表單.相似的,若是用戶輸入不合適的字符,輸入域上onkeypress事件處理程序能經過返回false來過濾輸入

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

理解事件處理程序的返回值只對經過屬性註冊的處理程序纔有意義這很是重要。接下來咱們將看到使用addEventListener或attchEvent註冊事件處理程序轉而必須調用preventDefault方法或設置事件對象returnValue屬性。

調用順序

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

經過設置對象屬性或HTML屬性註冊的處理程序一直優先調用。

使用addEventListener註冊的處理程序按照它們的註冊屬性調用。

使用attachEvent註冊的處理程序可能按照任何順序調用,全部代碼不該該依賴於調用順序。

在調用在目標元素上註冊的事件處理函數後,大部分事件會冒泡到Dom樹根。調用目標的父元素的事件處理程序,而後調用在目標的祖父元素上註冊的事件處理程序。這會一直到Document對象,最後到達window對象。發生在文檔元素上的大部分事件都會冒泡,值得注意的例外是focus、blur和scroll事件,文檔元素上的load事件會冒泡,但它會在Document對象上中止冒泡而不會傳播到Window對象。只有當整個文檔都加載完畢時纔會觸發window對象的load事件。

事件取消

在支持addEventListener的瀏覽器中,也能經過調用事件對象的preventDefault方法取消事件的默認操做。不過,在IE9以前的IE中,能夠經過設置事件對象的returnValue屬性爲false來達到false來達到一樣的效果。

取消事件相關的默認操做只是事件取消的一種,咱們也能取消事件傳播。在支持addEventListener的瀏覽器中,能夠調用事件對象的一個stopPropagation方法已阻止事件的繼續傳播。若是在同一對象上定義了其餘處理程序。剩下的處理程序將依舊被調用,但調用stopPropagation以後任何其餘對象上的事件處理程序將不會被調用。stopPropatation方法能夠在事件傳播期間的任什麼時候間調用,它能工做在捕獲階段、事件目標自己中和冒泡階段。ie9以前的IE不支持stopPropagation方法。相反,ie事件對象有一個cancelBubble屬性,設置這個屬性爲true能阻止事件進一步傳播(ie8及以前版本不支持事件傳播的捕獲階段,因此冒泡是惟一待取消的事件傳播)

事件捕獲提供了事件沒有送達目標以前查看它們的機會。事件捕獲能用於程序調試或用於後面介紹的事件取消技術,過濾掉事件從而是目標處理程序不會被調用。事件捕獲經常使用月處理鼠標拖放,由於要處理拖放事件的位置不能是這個元素內部的子元素

 文檔加載事件

Window的load事件直到文檔和全部圖片加載完畢才發生。當文檔加載解析完畢且全部延遲腳本都執行完畢時會觸發DOMContentLoaded事件,此時圖片和異步腳本可能依舊在加載,可是文檔已經爲操做準備就緒了,被包括IE9在內的全部其餘瀏覽器廠商採用

document.readyState屬性隨着文檔加載過程而變,在IE中,每次狀態變化都伴隨着document對象上的readystatechange事件,當ie接收到completely狀態時使用這個事件來判斷是可行的。

鼠標事件

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

mouseover 當鼠標進入元素時觸發,relatedtarget(在ie中是fromElement)指的是鼠標來自的元素

mouseout 當鼠標離開元素時觸發,relatedTarget(在ie中是toElement)指的是鼠標要去往的元素

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

altkey,ctrlkey,metakey和shiftkey屬性指定了當事件發生時是否有各類鍵盤輔助鍵按下,例如,這讓你可以區分普通單擊和按着shift鍵的單擊

鼠標滾輪事件

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

相關文章
相關標籤/搜索