摘要:及更早版本不支持事件流。綁定作用域其他的地方,就跟類似,都可以綁定多個事件處理程序,要刪除只能調用,并且不能使用匿名函數的形式。
事件知識快速入門
事件是前端開發必備的知識,我通過閱讀《JavaScript高級程序設計》,梳理了一下整個事件的知識體系,下面一起來學習吧。
1. 背景知識跟所有開發UI的思路一樣,JavaScript與HTML之間通過事件來進行交互。事件,就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間,我們使用監聽器(listener/hanlder)來預訂事件,當事件觸發時,執行相對應的代碼,這種就是傳統軟件工程中被成為觀察者模式的模型,這種模型支持頁面的行為與頁面的UI之間的松散耦合。
2. 事件流理解事件流,我們可以從一個問題出發,那就是:頁面的哪一個部分會擁有某個特定的事件?當我們點擊了一個button時,點擊事件不僅發生在按鈕上,換句話說,在單擊按鈕的同時,也是單擊了按鈕的容器元素,甚至也單擊了整個頁面。
這便有了事件流的概念,它描述的就是從頁面中接收事件的順序。而事件流有兩種:
事件冒泡
事件捕獲
早期,IE和Netscape的事件流順序是相反的,IE是事件冒泡流,Netscape是事件捕獲流。
2.1 事件冒泡IE的事件流叫做事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播到較為不具體的節點。
例如:
Event Bubbling click
當我們點擊頁面中的div元素時,這個click事件會按照如下的順序傳播
IE9、firefox、chrome和safari會將事件一直冒泡到window對象。
2.2 事件捕獲NetScape提出的另一種事件流叫做事件捕獲,即是不太具體的節點應該更早接收到事件,而最具體的節點應該最后接收到事件,它的用意在于事件到達預定目的之前捕獲它。
還是以上面的html代碼為例子,則當我們點擊頁面的div元素時,這個click事件的順序為:
2.3 DOM 事件流DOM2級事件規定事件流包括三個階段:
事件捕獲階段,為截獲事件提供了機會
處于目標階段,實際的目標接收到事件
事件冒泡階段,也可以在這個階段對事件作出響應
需要注意的有兩點:
盡管DOM2級事件規范要求事件應該從document對象開始傳播,但是大多數瀏覽器都是從window對象開始捕獲的。
DOM2級明確要求捕獲階段不會涉及事件目標,但是IE9,safari,chrome,firefox和opera9.5都會在捕獲階段觸發事件對象上的事件,結果,就是有兩個機會在目標對象上操作事件。
IE8及更早版本不支持DOM事件流。
3. 事件處理程序事件是用戶或瀏覽器自身執行的某種動作,而響應某個事件的函數就叫做事件處理程序。
設置事件處理程序的方式有4種,以下來一一介紹。
3.1 HTML事件處理程序某個元素支持的事件,都可以使用一個與相應事件處理程序同名的HTML屬性來指定,這個屬性的值應該是能夠執行的JavaScript代碼,例如:
我們可以直接在屬性中的js代碼中通過event變量獲取到event對象,代碼中的this指的是事件的目標元素。
這種方式在很多古老的頁面中都可以看到,它比較的簡單,粗暴。但是它導致了HTML與JavaScript代碼緊密耦合,從實踐的角度上,最好不要采用這樣的形式。
3.2 DOM0級事件處理程序通過JavaScript指定的事件處理程序的傳統方式,就是將一個函數賦值給一個事件處理程序屬性。
這個方式有兩個優點:
簡單
跨瀏覽器,至今所有的現代瀏覽器都支持。
var btn = document.getElementById("btn"); btn.onclick = function (event) { alert(event.type); alert(this.id); }
需要注意的是,通過這個方式進行設置,我們無法對同一個元素的同一個事件綁定多個事件處理程序(會覆蓋),例如以下代碼,就只會執行最后設置的函數。
var btn = document.getElementById("btn"); btn.onclick = function (event) { // 不會執行 alert(event.type); alert(this.id); } btn.onclick = function (event) { alert("覆蓋了"); }
依據這個特性,我們可以通過btn.onclick = null來刪除設置的事件處理程序。當然我們也可以通過以下的技巧,來為其綁定多個事件處理程序。
var btn = document.getElementById("btn"); btn.onclick = function (event) { alert(event.type); alert(this.id); } var oldHandler = btn.onclick; // 獲取前面設置的事件處理程序 btn.onclick = function (event) { oldHandler.call(this, event); alert("覆蓋了"); }3.3 DOM2級事件處理程序
DOM2級事件定義了兩個方法,用于處理指定和刪除事件程序的操作
addEventListener(type, listener, isCapture)
removeEventListener(type, listener, isCapture)
它們接收三個參數:
要處理的事件名(不需要帶on,例如點擊事件是click)
作為事件處理程序的函數
布爾值,為true時表示捕獲階段調用事件處理程序,為false則表示冒泡階段調用事件處理程序
var btn = document.getElementById("btn"); btn.addEventListener("click", function (event) { alert(event.type); alert(this.id); }, false);
使用這個方式的主要好處就是可以添加多個事件處理程序
var btn = document.getElementById("btn"); btn.addEventListener("click", function (event) { alert(event.type); alert(this.id); }, false); btn.addEventListener("click", function (event) { alert("hello world"); }, false);
通過addEventListener方式添加的事件處理程序只能通過removeEventListener來刪除,這就是說如果我們采用匿名函數的方式來添加事件處理程序的話,則無法進行刪除,因此比較好的方式就是:
var btn = document.getElementById("btn"); function handler(event) { alert(event.type); alert(this.id); } btn.addEventListener("click", handler, false); btn.removeEventListener("click", handler, false);
在大多數情況下,都是將事件處理程序添加到事件流的冒泡階段,這樣可以最大限度地兼容各種瀏覽器。
3.4 IE事件處理程序IE實現了與DOM中類似的兩個方法:
attachEvent(type, listener)
detachEvent(type, listener)
參數type是on+事件名,如點擊事件,則是onclick
由于IE8及更早版本只支持事件冒泡,所以通過attachEvent()添加事件處理程序都會被添加到冒泡階段。
Event Bubbling
上面的代碼其實是有問題的,當alert(this.id)時,會看到結果為undefined,這就是使用這個方法特別要注意的地方,事件處理程序會在全局作用域中運行,因此this等于window。
我們可以運用一個小技巧,來修復這個問題。
var btn = document.getElementById("btn"); function handler(event) { alert(event.type); alert(this.id); } btn.attachEvent("onclick", function (event){ handler.call(btn, event); // 綁定作用域 });
其他的地方,attachEvent()就跟addEventListener()類似,都可以綁定多個事件處理程序,要刪除只能調用detachEvent(),并且不能使用匿名函數的形式。
支持IE事件處理程序的瀏覽器有IE和Opera
4. 總結掌握了這些知識之后,我們就可以動手去編寫我們的跨瀏覽器的事件處理程序了^_^
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90963.html
摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現在已經一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現將已經寫好的文章整理一個目錄,方便更多的小伙伴去學習。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...
摘要:獲取元素距離的位置返回值為對象獲取相對于其最近的有定位的父元素的位置。不僅提供了更加優雅的事件處理語法,而且極大的增強了事件的處理能力。注冊簡單事件表示給綁定事件,并且由自己觸發,不支持動態綁定。 jQuery特殊屬性操作 val方法 val方法用于設置和獲取表單元素的值,例如input、textarea的值 //設置值 $(#name).val(張三); //獲取值 $(#name)...
摘要:前端最基礎的就是。幫助從舊的事件方法轉換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數。用于過濾器的觸發事件的選擇器元素的后代。事件觸發模擬觸發原生使用觸發。 前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS)...
摘要:前端最基礎的就是。幫助從舊的事件方法轉換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數。用于過濾器的觸發事件的選擇器元素的后代。事件觸發模擬觸發原生使用觸發。 前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS)...
閱讀 1838·2021-09-23 11:21
閱讀 700·2019-08-30 15:55
閱讀 834·2019-08-29 15:40
閱讀 530·2019-08-29 12:56
閱讀 3159·2019-08-26 12:00
閱讀 3554·2019-08-23 18:24
閱讀 2248·2019-08-23 17:08
閱讀 1639·2019-08-23 17:03