[置頂] 瀏覽器事件對象詳解


客戶端js程序采用了異步事件驅動模型,每當我們點擊或敲擊鍵盤時,瀏覽器就會產生事件,如果js程序關注特定類型的事件,那么它可以注冊當這類事件發生時要調用的一個或多個處理函數。這種風格並不止應用於web編程,所有使用圖形用戶界面的應用程序都采用了它。它們等待事件發生,然后它們響應。
事件類型(event type)是一個用來說明發生什么類型事件的字符串,例如mouseover表示用戶移動鼠標,keydown表示鍵盤上某個按鍵被按下。
事件目標(event target)是發生的事件或與之相關的目標。
事件處理程序(event handler)或事件監聽程序(event listener)是處理或響應事件的函數。當在特定的目標上發生特定類型的事件時,瀏覽器會調用對應的處理程序,當對象上注冊的事件處理程序被調用時,我們有這樣幾種等價的說法: 瀏覽器觸發(fire,trigger)或者派發(dispatch)了事件。
事件對象(event object)是與特定事件相關並且包含有關該事件,事件對象作為參數傳遞給事件處理函數。
事件傳播(event propagation)是瀏覽器決定哪個對象觸發其事件處理程序的過程。對於單個對象的特定事件(比如window對象的load事件),必須是不能傳播的。當文檔元素上發生某個類型的事件時,他們會在文檔樹上向上傳播或冒泡。有時在容器上注冊單個事件處理程序比在每個獨立的目標上都注冊處理程序要更方便。(在容器上注冊處理程序只是改變事件處理函數,並不能改變觸發的元素,觸發的元素正常都是最底層元素)。
事件傳播的另一種形式成為事件捕獲(event capturing),在容器上注冊的特定處理程序有機會在事件傳播到真實目標之前攔截它。

事件對象坐標

事件對象的坐標包括clientX和clientY,screenX和screenY, offsetX和offsetY,
pageX和pageY,X和Y。
clientX和clientY是相對於瀏覽器(可視區左上角的0, 0)的坐標
screenX和screenY是相對於設備屏幕左上角(0,0)的坐標
offsetX和offsetY是相對於事件源左上角(0,0)的坐標
pageX和pageY是相對於整個網頁左上角(0,0)的坐標
X和Y 本來是IE屬性,相對於用CSS動態定位的最內層包容元素。

表單事件

當提交表單和重置表單時,< form>元素會分別觸發submit和reset事件,當用戶和類表單元素交互時,它們會發生click事件。當用戶通過輸入文字,選擇選項或選擇復選框來改變相應表單元素的狀態時,這些通常維護某種狀態的表單元素會觸發change事件。對於文本輸入域,只有用戶和表單元素完成交互並通過Tab鍵或單擊的方式移動焦點到其他焦點到其他元素上才會觸發change事件(然而在React中,每次進行文本輸入都會出發change事件)。響應通過鍵盤改變焦點的表單元素在得到和失去焦點時會分別出發focus和blur事件

Window事件

Window事件是指事件的發生與瀏覽器窗口本身而非窗口中顯示的任何特定文檔內容相關,但是,這些事件中有一些會和文檔元素上發生的事件同名.
load事件是這些事件中最重要的一個,當文檔和其所有外部資源(比如圖片)完全加載並顯示給用戶時就會觸發它。
unload事件和load相對,當用戶離開當前文檔轉向其他文檔時會觸發它。
window對象的onerror屬性有點像事件處理程序,當js出錯時會觸發它。
像img元素也可以為load和error事件注冊處理程序,當外部資源完全加載或加載錯誤的時候就會觸發它們。H5支持abort事件,當圖片或其他網絡資源因為用戶停止加載進程而導致失敗就會觸發它
當用戶調整瀏覽器大小或滾動它時會觸發resize和scroll事件。scroll事件也可以在任何可以滾動的元素上觸發,比如那些設置CSS的overflow屬性為scroll的元素

鼠標事件

對於click事件,detail屬性指定了其是單擊,雙擊或三擊,clientX和clientY屬性指定了鼠標在窗口坐標中的位置
用戶每次移動或拖動鼠標時,會觸發mousemove事件,這些事件的發生非常頻繁,所以mousemove事件處理程序一定不能觸發計算密集型任務。
在mousedown和mouseup事件隊列之后,瀏覽器也會觸發click事件。懸停和移走會觸發mouseover(不論鼠標指針穿過被選元素或其子元素,都會觸發 mouseover 事件,只有在鼠標指針穿過被選元素時,才會觸發 mouseenter 事件)和mouseout事件。
keydown和keyup事件是低級鍵盤事件。當keydown事件產生可打印的字符時,在keydown和keyup之間會觸發另外一個keypress事件

HTML5事件

HTML5的拖放API提供了很多拖放事件,具體可以參考實現H5的拖放 。HTML5定義了歷史管理機制,它允許web應用同瀏覽器的返回和前進按鈕交互(pushState)。HTML5提供了解決跨域問題的message事件,也提供了storage事件來監聽數據的本地存取。

觸摸屏和移動設備事件

旋轉移動設備產生的orientationchange事件,手勢開始時生成gesturestart事件,而手勢結束時生成gestureend事件,在兩個事件之間是跟蹤手勢過程的gesturechange事件。如果想實現自定義手勢,可以監聽touchstart事件和touchmove事件。

注冊事件處理程序

最簡單的方式就是通過on + 事件名稱注冊事件回調處理函數。這種方法兼容性好,缺點是圍繞每個事件目標對於每種事件類型最多只能有一個事件處理程序(有多個文檔時或引用多個依賴時會出現重寫的問題)

addEventListener

addEventListener不影響on綁定的事件處理,同時它能注冊多個處理函數

   function fn1(){
alert('fn1');
}
function fn2(){
alert('fn2');
}
function fn3(){
alert('fn3');
}
var btn = document.getElementById('button');
btn.onclick = fn1;
//第三個參數false為事件冒泡,true為事件捕獲
btn.addEventListener('click', fn2, false);
btn.addEventListener('click', fn3, false);
//點擊連續彈出3個彈窗(按順序)
//使用removeEventListener為處理函數解綁
btn.removeEventListener('click', fn3, false);

IE8及其以下瀏覽器不支持這兩個函數,IE中有類似的函數attachEvent(以這個函數注冊的處理順序可能按照任何順序調用),所以需要封裝一個兼容函數

事件處理程序的運行環境

在事件處理程序內,this關鍵字指的是事件目標。而使用attachEvent注冊的事件處理函數,this的指向是window,所以要在其中使用call或者apply來改變this指向。

事件處理函數的作用域

事件處理函數的作用域是定義時的作用域(經常通過閉包獲得外部變量)。但是通過HTML屬性注冊事件處理程序是一個例外,他們被轉換成能存取全局變量的頂級函數而非任何本地變量

事件處理程序的返回值

通常情況下,返回值false是告訴瀏覽器不要執行這個事件相關的默認操作,例如表單提交按鈕的onclick事件處理函數返回false就能組織瀏覽器提交表單。如果用戶輸入不合適的字符,輸入域上的onkeypress事件處理就能通過返回false來過濾鍵盤輸入。返回false的兼容性很好。

事件傳播

在調用在目標元素上注冊的事件處理函數之后,大部分事件會冒泡到DOM樹根,調用目標的父元素的事件處理程序,然后調用在目標的祖先元素上注冊的事件處理程序。事件冒泡為大量單獨文檔元素上注冊程序提供了更好的方案,即在共同的祖先元素上注冊一個處理程序來處理所有的事件。例如可以在< form>元素上注冊change事件來取代表單上每個元素上的每個元素上注冊change事件處理程序。還有像選項卡中要獲取li的索引,可以通過直接在ul上注冊事件,然后通過事件的target來判斷是哪一個li被點擊了
事件冒泡是事件傳播的第三個階段,目標對象本身的事件處理程序調用是第二個階段,第一個階段發生在目標處理程序調用之前,成為捕獲階段,事件捕獲只能通過addEventListener 注冊,這意味者事件捕獲在IE8之前無法使用。

事件取消

在支持addEventListener 的瀏覽器中,也能通過調用事件對象的preventDefault()方法取消事件的默認操作。在IE9之前的IE中,可以通過設置事件對象的returnValue為false來達到相同的效果。下面假設一個事件處理程序,通過能力檢測來判斷瀏覽器支持程度

   function cancelHandler(event){
//省略其他處理
//window.event用於IE
var event = event || window.event;
if(event.preventDefault) event.preventDefault();
//IE
if(event.returnValue) event.returnValue = false;
return false;
}

使用stopPropagation 之后,除了在同一個對象上定義的其他事件處理函數,其他對象上的事件處理程序將不會被調用。IE9之前的IE不支持stopPropagation,IE有一個cancelBubble屬性,設置為true可以達到相同效果


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com