摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個我們既然知道了第二個產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。
本文探索一下Event的冒泡過程和初學(xué)遇到的幾個小bugDOM Event概述
Event接口是檢測在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來的火狐)和IE是各自為戰(zhàn),直到W3C一統(tǒng)江湖,DOM版本一路發(fā)展而來,經(jīng)歷了DOM-0(洪荒時代)、DOM-1(只有兩章核心內(nèi)容)、DOM-2(劃時代的一個版本,我們學(xué)的Event就在這個版本,而且目前的用的也是這個版本)、DOM-3、DOM-4(草案階段)。
通過一個例子喚醒對Event的認識
//1、有一個js函數(shù)如下 function print(){ console.log(1) } //2、在html的button里面點擊觸發(fā)上面的函數(shù) //問號處填可以填什么 A. print() B.print C.print.call() //在js里面的onclick里面觸發(fā) button.onclick = ? //問號處可以填什么 A. print() B.print C.print.call()
很明顯第一個問號應(yīng)該選A C,第二個問號應(yīng)該選B
第一處在HTM中,點擊事件要立刻執(zhí)行代碼,肯定選擇帶()的,而第二處在JS中,onclick是一個屬性,不需要立刻執(zhí)行,等用戶點擊了,瀏覽器再反應(yīng),不需要()。
既然onclick等on事件在JS中是一個屬性,那么后面的就會覆蓋前面的,所以DOM2里面引入了一個重要的EventListener,是一個隊列。
addEventListener這是一個隊列,例子1,先進先出的特點,為后面的冒泡模型做準備。
function f(){ console.log("eventListener不會覆蓋") } button2.addEventListener("click", function(){ console.log("eventListener不會覆蓋1") }) button2.addEventListener("click", f) button2.removeEventListener("click", f) button2.addEventListener("click", function(){ console.log("eventListener不會覆蓋3") })
會打印出什么呢,答案是eventListener不會覆蓋1 eventListener不會覆蓋3
所以說既然on可以一個打印出結(jié)果,就可以借助remove來實現(xiàn)one執(zhí)行一次的操作
function f(){ console.log("eventListener不會覆蓋2") button2.removeEventListener("click", f) } button2.addEventListener("click", f)
只會打印一次,不會一直打印了,也就是one的原理。
具體的模型可以看W3C
冒泡模型上面的官方文檔中,我只研究一下捕獲階段(capture phase)和冒泡階段(bubbling phase)。
什么是冒泡呢?我們先看一段代碼
grand.addEventListener("click", function(){ console.log("我是你爺爺") }) dad.addEventListener("click", function(){ console.log("我是你爸爸") }) son.addEventListener("click", function(){ console.log("我是你兒子") })
這是三個div的事件,當你點擊的時候,控制臺打印必然會有順序。那么應(yīng)該是什么順序呢,正常人的思維不外乎兩種結(jié)果
第一種:我是你的兒子 我是你爸爸 我是你爺爺
第二種: 我是你爺爺 我是你爸爸 我是你兒子
到底是那種呢,W3C說都行,看你代碼咋寫的了,上面的代碼打印順序是第一個中,也就是冒泡。
如果你想實現(xiàn)第二種打印方式,也就是捕獲階段,應(yīng)該修改代碼如下
grand.addEventListener("click", function(){ console.log("我是你爺爺") }, true) dad.addEventListener("click", function(){ console.log("我是你爸爸") }, true) son.addEventListener("click", function(){ console.log("我是你兒子") }, true)
也就是說addEventListener后面的參數(shù)決定了順序,當你不寫的時候是undefined,也就是false的意思。
復(fù)習(xí)一下五個falsey值
0 NaN "" null undefined 除此之外都是true
上圖是簡單的圖解,注意優(yōu)先運行為true的部分,再運行false的部分。
簡單的實例====================>demo
一個變式
grand.addEventListener("click", function(){ console.log("我是你爺爺") }, true) dad.addEventListener("click", function(){ console.log("我是你爸爸") }) son.addEventListener("click", function(){ console.log("我是你兒子")
上述代碼應(yīng)該是什么順序呢
誰是true,先打印誰,都是false,繼續(xù)按照冒泡順序打印。
一個奇葩的問題son.addEventListener("click", function(){ console.log("我是你兒子true") }, true) son.addEventListener("click", function(){ console.log("我是你兒子false") })
給同一個元素 false true,應(yīng)該打印什么呢
答案是: 按照書寫的順序,誰在前面先打印誰。
意想不到的Bugparent是關(guān)鍵字不能使用,一不小心使用的話會出問題。
你用了關(guān)鍵字做變量,把鼠標點爛也看不到效果。
點擊空白,對話框消失的案例領(lǐng)導(dǎo)說有一個需求,點擊某個按鈕,彈出對話框,點擊空白會消失。
你的第一個思路:先把div設(shè)為none,點擊按鈕的時候,再讓這個div的display是block,點擊其他地方變?yōu)閚one。
很好,你去實現(xiàn)一下吧。
第一個bug
很快你會碰到了第一個bug
第一個錯誤:監(jiān)聽錯了對象
正常來說,應(yīng)該點擊body控制臺打印數(shù)字1,你點爛了你的羅技鼠標也沒出來。為什么呢?
我們使用border大法,看看它到底在哪
使用了紅色border之后,發(fā)現(xiàn)body的高度太矮了,點擊不到啊。
你明白監(jiān)聽錯對象了,那你就換了一個對象,監(jiān)聽文檔唄,肯定沒問題了。
第二個bug
很好,你進入了第二個bug了
第二個bug:你都能點擊到,但是彈不出對話框了
根據(jù)圖片 中的控制臺可以發(fā)現(xiàn),確實都點擊到了,監(jiān)聽沒問題,而且點擊后,也是按照冒泡的順序打印的結(jié)果。
那為什么沒有對話框了呢
注釋掉出問題的代碼后,上圖是正常的點擊出現(xiàn)對話框啊,說明問題就出在注釋的代碼上。
bug出現(xiàn)的原因就在于:默認冒泡的影響,當你點擊的浮層那個div,之后,往 body document上冒泡,在document上立刻被殺死,display變?yōu)閚one,你做夢能看到 彈出框啊。
修復(fù)第二個bug我們既然知道了第二個bug產(chǎn)生的原因,那么我們阻止冒泡順序
解決的方案,不讓其往上冒泡,自己管理。
clickMe.addEventListener("click", function(){ popover.style.display = "block" console.log("點擊浮層了") }) wrapper.addEventListener("click", function(e){ e.stopPropagation() }) document.addEventListener("click", function(){ popover.style.display = "none" console.log("點擊文檔了") })
但是隨之而來的是一個關(guān)于內(nèi)存占用的問題,現(xiàn)在你是只有一個popover,只有一個函數(shù),等你有了很多個popover,如果按照這個寫法會有很多個函數(shù),所以不能這么寫,采用下面的寫法,節(jié)省內(nèi)存。
$(clickMe).on("click", function(){ $(popover).show() console.log("show") setTimeout(function(){ console.log("one click") $(document).one("click", function(){ console.log("我覺的他不會執(zhí)行") $(popover).hide() }) },0) }) // $(wrapper).on("click", function(e){ // e.stopPropagation() // }) $(document).on("click", function(){ console.log("走到document啦") })
只有點擊的時候才用,設(shè)置settimeout是為了讓他異步,不至于立刻隱藏,產(chǎn)生第一個bug。
注意一下,jQuery的 show() hide()
當你點擊按鈕,只會打印圖中這兩句話,另外兩句只有再次點擊才會打印。
JS版本的節(jié)省內(nèi)存的版本==================>節(jié)省內(nèi)存
jQuery版本的節(jié)省內(nèi)存版本=================>jQuery節(jié)省內(nèi)存
對話框小三角的制作.popover{ display: inline-block; border: 1px solid red; position: relative; padding: 10px; margin:10px; } .popover::before{ position: absolute; content: ""; top: 5px; right: 100%; border: 10px solid transparent; border-right-color:red; } .popover::after{ content: ""; border: 10px solid transparent; position: absolute; right: 100%; top: 5px; border-right-color: white; margin-right: -1px; }
主要利用boder-right-color以及兩個偽元素。
浮層三角的實例=============================>demo
冒泡的直觀體現(xiàn)點擊一下會有驚喜的https://github.com/codevvvv9/bubble/blob/master/bubble.gif
冒個泡
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/92508.html
摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個我們既然知道了第二個產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。 本文探索一下Event的冒泡過程和初學(xué)遇到的幾個小bug DOM Event概述 Event接口是檢測在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來的火狐)和IE...
摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個我們既然知道了第二個產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。 本文探索一下Event的冒泡過程和初學(xué)遇到的幾個小bug DOM Event概述 Event接口是檢測在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來的火狐)和IE...
摘要:事件相關(guān)內(nèi)容當用戶與瀏覽器發(fā)生的一些交互時如果希望去獲得用戶行為就需要借助事件來完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識如下這也是面試中遇到的問題事件的級別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對象常見的 DOM事件相關(guān)內(nèi)容 當用戶與瀏覽器發(fā)生的一些交互時, 如果希望去獲得用戶行為, 就需要借助事件來完成. 事件部分內(nèi)容在 JS中重要性不言而喻. ...
摘要:事件相關(guān)內(nèi)容當用戶與瀏覽器發(fā)生的一些交互時如果希望去獲得用戶行為就需要借助事件來完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識如下這也是面試中遇到的問題事件的級別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對象常見的 DOM事件相關(guān)內(nèi)容 當用戶與瀏覽器發(fā)生的一些交互時, 如果希望去獲得用戶行為, 就需要借助事件來完成. 事件部分內(nèi)容在 JS中重要性不言而喻. ...
閱讀 1268·2023-04-26 01:38
閱讀 1469·2021-11-15 11:39
閱讀 3259·2021-09-22 15:43
閱讀 2653·2019-08-30 15:55
閱讀 2057·2019-08-30 14:17
閱讀 2859·2019-08-29 14:16
閱讀 3071·2019-08-26 18:36
閱讀 2616·2019-08-26 12:19