摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現代瀏覽器都支持事件冒泡,并且會將事件一直冒泡到對象。事件捕獲的用以在于事件到達預定目標之前捕獲它。事件流級事件規定事件流包括三個階段,事件捕獲階段處于目標階段和事件冒泡階段。
最近在復習前端的基礎,看到事件這一節的時候,剛好發現了筆記中一道特別好玩并且十分有趣的代碼,根據這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區給掃空。本文就帶你一起來看看這段有趣的代碼。
但是,首先我們還是要例行公事,把一些基礎的概念過一過,其實也不需要太長的時間。
什么是事件?JavaScript和HTML之間的交互是通過事件實現的。事件,就是文檔或瀏覽器窗口發生的一些特定的交互瞬間。可以使用監聽器(或事件處理程序)來預定事件,以便事件發生時執行相應的代碼。通俗的說,這種模型其實就是一個觀察者模式。(事件是對象主題,而這一個個的監聽器就是一個個觀察者)事件流
事件流描述的就是從頁面中接收事件的順序。而IE和Netscape提出了完全相反的事件流概念。IE事件流是事件冒泡,而Netscape的事件流就是事件捕獲。
打個比喻,如果你把手指放在圓心上(多個同心圓),那么你的手指指向的不是一個圓,而是紙上所有的圓。如果你單擊了某個按鈕,在單擊按鈕的同時,也單擊了按鈕的容器元素,甚至是整個頁面。
事件冒泡IE的事件流叫做事件冒泡。即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播到較為不具體的節點(文檔)。所有現代瀏覽器都支持事件冒泡,并且會將事件一直冒泡到window對象。事件捕獲
事件捕獲的思想是不太具體的節點應該更早的接收到事件,而在最具體的節點應該最后接收到事件。事件捕獲的用以在于事件到達預定目標之前捕獲它。IE9+、Safari、Chrome、Opera和Firefox支持,且從window開始捕獲(盡管DOM2級事件規范要求從document)。由于老版本瀏覽器不支持,所以很少有人使用事件捕獲。DOM事件流
“DOM2級事件”規定事件流包括三個階段,事件捕獲階段、處于目標階段和事件冒泡階段。首先發生的事件捕獲,為截獲事件提供了機會。然后是實際的目標接收了事件。最后一個階段是冒泡階段,可以在這個階段對事件做出響應。
以上這段話,就是我們DOM事件流的根本了,這段話非常重要,雖然看似簡單,但是里面包含著很多小細節,我會在下面例子中全部講到。
一個十分有趣的例子現在就開始來講解這個有趣的例子,先把代碼貼上來,大致的結構十分簡單。由于segmentfault代碼過長時會有滾動條,這里我把它切分,并省略了一些不必要的結點,便于觀看。
#a{ width: 300px; height: 300px; background: pink; } #b{ width: 200px; height: 200px; background: blue; } #c{ width: 100px; height: 100px; background: yellow; }
var a = document.getElementById("a"), b = document.getElementById("b"), c = document.getElementById("c"); c.addEventListener("click", function (event) { console.log("c1"); // 注意第三個參數沒有傳進 false , 因為默認傳進來的是 false //,代表冒泡階段調用,個人認為處于目標階段也會調用的 }); c.addEventListener("click", function (event) { console.log("c2"); }, true); b.addEventListener("click", function (event) { console.log("b"); }, true); a.addEventListener("click", function (event) { console.log("a1"); }, true); a.addEventListener("click", function (event) { console.log("a2") }); a.addEventListener("click", function (event) { console.log("a3"); event.stopImmediatePropagation(); }, true); a.addEventListener("click", function (event) { console.log("a4"); }, true);
整個的html頁面就是下面這三個小盒子。
那么現在有三個問題:
如果點擊c或者b,輸出什么?(答案是a1、a3)
stopImmediatePropagation包含了stopPropagation的功能,即阻止事件傳播(捕獲或冒泡),但同時也阻止該元素上后來綁定的事件處理程序被調用,所以不輸出 a4。因為事件捕獲被攔截了,自然不會觸發 b、c 上的事件,所以不輸出 b、c1、c2,冒泡更談不上了,所以不輸出 a2。
如果點擊a,輸出什么?(答案是 a1、a2、a3)
不應該是 a1、a3、a2 嗎?有同學就會說:“a1、a3可是在捕獲階段被調用的處理程序的,a2 是在冒泡階段被調用的啊。”這正是要說明的:雖然這三個事件處理程序注冊時指定了true、false,但現在事件流是處于目標階段,不是冒泡階段、也不是捕獲階段,事件處理程序被調用的順序是注冊的順序。不論你指定的是true還是false。換句話來說就是現在點擊的是a這個盒子本身,它處于事件流的目標狀態,而既非冒泡,又非捕獲。(需要注意的是,此時的eventPhase為2,說明事件流處于目標階段。當點擊a的時候,先從document捕獲,然后一步步往下找,找到a這個元素的時候,此時的target和currentTarget是一致的,所以認定到底了,不需要再捕獲了,此時就按順序執行已經預定的事件處理函數,執行完畢后再繼續往上冒泡...)
如果注釋掉event.stopImmediatePropagation,點擊c,會輸出什么?(答案是 a1、a3、a4、b、c1、c2、a2)
如果同一個事件處理程序(指針相同,比如用 handler 保存的事件處理程序),用 addEventListener或 attachEvent綁定多次,如果第三個參數是相同的話,也只會被調用一次。當然,如果第三個參數一個設置為true,另一個設置為false,那么會被調用兩次。
而在這里,都是給監聽函數的回調賦予了一個匿名函數,所以其實每個處理函數都會被調用。需要注意的是,如果你還不明白為什么在c上觸發的先是c1再是c2的話,那么你就需要在去看看第二個問題所描述的內容了。
以上,就是本文章的內容,文章最后的例子是從網上某個地方看到的,但是具體的出處已經忘記了,如果有同學找到了出處,煩請告知。
參考資料:《JavaScript高級程序設計》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/51661.html
摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現代瀏覽器都支持事件冒泡,并且會將事件一直冒泡到對象。事件捕獲的用以在于事件到達預定目標之前捕獲它。事件流級事件規定事件流包括三個階段,事件捕獲階段處于目標階段和事件冒泡階段。 最近在復習前端的基礎,看到事件這一節的時候,剛好發現了筆記中一道特別好玩并且十分有趣的代碼,根據這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區給掃空。本文就帶你...
摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現代瀏覽器都支持事件冒泡,并且會將事件一直冒泡到對象。事件捕獲的用以在于事件到達預定目標之前捕獲它。事件流級事件規定事件流包括三個階段,事件捕獲階段處于目標階段和事件冒泡階段。 最近在復習前端的基礎,看到事件這一節的時候,剛好發現了筆記中一道特別好玩并且十分有趣的代碼,根據這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區給掃空。本文就帶你...
摘要:基礎最后一篇啦,蹭著周六日趕緊寫完,其他的都是的或者瀏覽器能力,高級技巧,使用等雜七雜八的知識點,這里就不一一介紹了,平時編碼也用不太到,有興趣的可以找找相關的書籍前言先說說事件流吧,事件流就是從從開始到目標節點之前的節點進行事件的捕獲,在 基礎最后一篇啦,蹭著周六日趕緊寫完,其他的都是DOM,BOM的api或者瀏覽器能力,高級技巧,Canvas使用等雜七雜八的知識點,這里就不一一介紹...
摘要:所有節點中都包含這兩個方法,并且它們都接收個參數要處理的事件名作為事件處理程序的函數和一個布爾值。當這個布爾值為時,表示在捕獲階段調用事件處理程序若果是,表示在冒泡階段調用事件處理程序。 事件流 定義: 1.事件流描述的是從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。 2.事件就是用戶或瀏覽器自身執行的某種動作。諸如click(點擊)、load(加載)、mouseover(...
摘要:通過管理組件通信通過驅動視圖比較差異進行更新操作作者第七頁鏈接來源知乎著作權歸作者所有,轉載請聯系作者獲得授權。達到無刷新的效果。對象的狀態不受外界影響。對象代表一個異步操作,有三種狀態進行中已完成,又稱和已失敗。 以下問題解釋非本人原創,是根據面試經驗整理后覺得更容易理解的解釋版本,歡迎補充。 一. 輸入url后的加載過程 從輸入 URL 到頁面加載完成的過程中都發生了什么 計算機...
閱讀 3563·2023-04-25 16:35
閱讀 699·2021-10-11 11:09
閱讀 6162·2021-09-22 15:11
閱讀 3355·2019-08-30 14:03
閱讀 2597·2019-08-29 16:54
閱讀 3350·2019-08-29 16:34
閱讀 3053·2019-08-29 12:18
閱讀 2123·2019-08-28 18:31