国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

理解Event冒泡模型

MadPecker / 2719人閱讀

摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個(gè)我們既然知道了第二個(gè)產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。

本文探索一下Event的冒泡過(guò)程和初學(xué)遇到的幾個(gè)小bug
DOM Event概述

Event接口是檢測(cè)在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來(lái)的火狐)和IE是各自為戰(zhàn),直到W3C一統(tǒng)江湖,DOM版本一路發(fā)展而來(lái),經(jīng)歷了DOM-0(洪荒時(shí)代)、DOM-1(只有兩章核心內(nèi)容)、DOM-2(劃時(shí)代的一個(gè)版本,我們學(xué)的Event就在這個(gè)版本,而且目前的用的也是這個(gè)版本)、DOM-3、DOM-4(草案階段)。

通過(guò)一個(gè)例子喚醒對(duì)Event的認(rèn)識(shí)

//1、有一個(gè)js函數(shù)如下
function print(){
  console.log(1)
}

//2、在html的button里面點(diǎn)擊觸發(fā)上面的函數(shù)

//問(wèn)號(hào)處填可以填什么 A. print() B.print C.print.call()

//在js里面的onclick里面觸發(fā)
button.onclick = ?
//問(wèn)號(hào)處可以填什么 A. print() B.print C.print.call()

很明顯第一個(gè)問(wèn)號(hào)應(yīng)該選A C,第二個(gè)問(wèn)號(hào)應(yīng)該選B

第一處在HTM中,點(diǎn)擊事件要立刻執(zhí)行代碼,肯定選擇帶()的,而第二處在JS中,onclick是一個(gè)屬性,不需要立刻執(zhí)行,等用戶點(diǎn)擊了,瀏覽器再反應(yīng),不需要()

既然onclick等on事件在JS中是一個(gè)屬性,那么后面的就會(huì)覆蓋前面的,所以DOM2里面引入了一個(gè)重要的EventListener,是一個(gè)隊(duì)列。

addEventListener

這是一個(gè)隊(duì)列,例子1,先進(jìn)先出的特點(diǎn),為后面的冒泡模型做準(zhǔn)備。

function f(){
  console.log("eventListener不會(huì)覆蓋")
}

button2.addEventListener("click", function(){
  console.log("eventListener不會(huì)覆蓋1")
})
button2.addEventListener("click", f)
button2.removeEventListener("click", f)
button2.addEventListener("click", function(){
  console.log("eventListener不會(huì)覆蓋3")
})

會(huì)打印出什么呢,答案是eventListener不會(huì)覆蓋1 eventListener不會(huì)覆蓋3

所以說(shuō)既然on可以一個(gè)打印出結(jié)果,就可以借助remove來(lái)實(shí)現(xiàn)one執(zhí)行一次的操作

function f(){
  console.log("eventListener不會(huì)覆蓋2")
  button2.removeEventListener("click", f)
}


button2.addEventListener("click", f)

只會(huì)打印一次,不會(huì)一直打印了,也就是one的原理。

具體的模型可以看W3C

冒泡模型

上面的官方文檔中,我只研究一下捕獲階段(capture phase)和冒泡階段(bubbling phase)。

什么是冒泡呢?我們先看一段代碼

grand.addEventListener("click", function(){
  console.log("我是你爺爺")
})
dad.addEventListener("click", function(){
  console.log("我是你爸爸")
})

son.addEventListener("click", function(){
  console.log("我是你兒子")
})

這是三個(gè)div的事件,當(dāng)你點(diǎn)擊的時(shí)候,控制臺(tái)打印必然會(huì)有順序。那么應(yīng)該是什么順序呢,正常人的思維不外乎兩種結(jié)果

第一種:我是你的兒子 我是你爸爸 我是你爺爺

第二種: 我是你爺爺 我是你爸爸 我是你兒子

到底是那種呢,W3C說(shuō)都行,看你代碼咋寫的了,上面的代碼打印順序是第一個(gè)中,也就是冒泡。

如果你想實(shí)現(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)

也就是說(shuō)addEventListener后面的參數(shù)決定了順序,當(dāng)你不寫的時(shí)候是undefined,也就是false的意思。

復(fù)習(xí)一下五個(gè)falsey

0 NaN "" null undefined 除此之外都是true

上圖是簡(jiǎn)單的圖解,注意優(yōu)先運(yùn)行為true的部分,再運(yùn)行false的部分。

簡(jiǎn)單的實(shí)例====================>demo

一個(gè)變式

grand.addEventListener("click", function(){
  console.log("我是你爺爺")
}, true)
dad.addEventListener("click", function(){
  console.log("我是你爸爸")
})

son.addEventListener("click", function(){
  console.log("我是你兒子")

上述代碼應(yīng)該是什么順序呢

誰(shuí)是true,先打印誰(shuí),都是false,繼續(xù)按照冒泡順序打印。

一個(gè)奇葩的問(wèn)題
son.addEventListener("click", function(){
  console.log("我是你兒子true")
}, true)

son.addEventListener("click", function(){
  console.log("我是你兒子false")
})

給同一個(gè)元素 false true,應(yīng)該打印什么呢

答案是: 按照書寫的順序,誰(shuí)在前面先打印誰(shuí)。

意想不到的Bug

parent是關(guān)鍵字不能使用,一不小心使用的話會(huì)出問(wèn)題。

你用了關(guān)鍵字做變量,把鼠標(biāo)點(diǎn)爛也看不到效果。

點(diǎn)擊空白,對(duì)話框消失的案例

領(lǐng)導(dǎo)說(shuō)有一個(gè)需求,點(diǎn)擊某個(gè)按鈕,彈出對(duì)話框,點(diǎn)擊空白會(huì)消失。

你的第一個(gè)思路:先把div設(shè)為none,點(diǎn)擊按鈕的時(shí)候,再讓這個(gè)div的display是block,點(diǎn)擊其他地方變?yōu)閚one。

很好,你去實(shí)現(xiàn)一下吧。

第一個(gè)bug

很快你會(huì)碰到了第一個(gè)bug

第一個(gè)錯(cuò)誤:監(jiān)聽錯(cuò)了對(duì)象

正常來(lái)說(shuō),應(yīng)該點(diǎn)擊body控制臺(tái)打印數(shù)字1,你點(diǎn)爛了你的羅技鼠標(biāo)也沒(méi)出來(lái)。為什么呢?

我們使用border大法,看看它到底在哪

使用了紅色border之后,發(fā)現(xiàn)body的高度太矮了,點(diǎn)擊不到啊。

你明白監(jiān)聽錯(cuò)對(duì)象了,那你就換了一個(gè)對(duì)象,監(jiān)聽文檔唄,肯定沒(méi)問(wèn)題了。

第二個(gè)bug

很好,你進(jìn)入了第二個(gè)bug了

第二個(gè)bug:你都能點(diǎn)擊到,但是彈不出對(duì)話框了

根據(jù)圖片 中的控制臺(tái)可以發(fā)現(xiàn),確實(shí)都點(diǎn)擊到了,監(jiān)聽沒(méi)問(wèn)題,而且點(diǎn)擊后,也是按照冒泡的順序打印的結(jié)果。

那為什么沒(méi)有對(duì)話框了呢

注釋掉出問(wèn)題的代碼后,上圖是正常的點(diǎn)擊出現(xiàn)對(duì)話框啊,說(shuō)明問(wèn)題就出在注釋的代碼上。

bug出現(xiàn)的原因就在于:默認(rèn)冒泡的影響,當(dāng)你點(diǎn)擊的浮層那個(gè)div,之后,往 body document上冒泡,在document上立刻被殺死,display變?yōu)閚one,你做夢(mèng)能看到 彈出框啊。

修復(fù)第二個(gè)bug

我們既然知道了第二個(gè)bug產(chǎn)生的原因,那么我們阻止冒泡順序

解決的方案,不讓其往上冒泡,自己管理。

clickMe.addEventListener("click", function(){
  popover.style.display = "block"
  console.log("點(diǎn)擊浮層了") 
})

wrapper.addEventListener("click", function(e){
  e.stopPropagation()
})


document.addEventListener("click", function(){
  popover.style.display = "none"
  console.log("點(diǎn)擊文檔了") 
})

但是隨之而來(lái)的是一個(gè)關(guān)于內(nèi)存占用的問(wèn)題,現(xiàn)在你是只有一個(gè)popover,只有一個(gè)函數(shù),等你有了很多個(gè)popover,如果按照這個(gè)寫法會(huì)有很多個(gè)函數(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("我覺(jué)的他不會(huì)執(zhí)行")
     $(popover).hide()            
    })
  },0)
  
})
// $(wrapper).on("click", function(e){
//   e.stopPropagation()
// })

$(document).on("click", function(){
  console.log("走到document啦")
})

只有點(diǎn)擊的時(shí)候才用,設(shè)置settimeout是為了讓他異步,不至于立刻隱藏,產(chǎn)生第一個(gè)bug。

注意一下,jQuery的 show() hide()

當(dāng)你點(diǎn)擊按鈕,只會(huì)打印圖中這兩句話,另外兩句只有再次點(diǎn)擊才會(huì)打印。

JS版本的節(jié)省內(nèi)存的版本==================>節(jié)省內(nèi)存

jQuery版本的節(jié)省內(nèi)存版本=================>jQuery節(jié)省內(nèi)存

對(duì)話框小三角的制作
.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以及兩個(gè)偽元素。

浮層三角的實(shí)例=============================>demo

冒泡的直觀體現(xiàn)

點(diǎn)擊一下會(huì)有驚喜的https://github.com/codevvvv9/bubble/blob/master/bubble.gif

冒個(gè)泡

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/51714.html

相關(guān)文章

  • 理解Event冒泡模型

    摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個(gè)我們既然知道了第二個(gè)產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。 本文探索一下Event的冒泡過(guò)程和初學(xué)遇到的幾個(gè)小bug DOM Event概述 Event接口是檢測(cè)在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來(lái)的火狐)和IE...

    zeyu 評(píng)論0 收藏0
  • 理解Event冒泡模型

    摘要:具體的模型可以看冒泡模型上面的官方文檔中,我只研究一下捕獲階段和冒泡階段。修復(fù)第二個(gè)我們既然知道了第二個(gè)產(chǎn)生的原因,那么我們阻止冒泡順序解決的方案,不讓其往上冒泡,自己管理。 本文探索一下Event的冒泡過(guò)程和初學(xué)遇到的幾個(gè)小bug DOM Event概述 Event接口是檢測(cè)在DOM中的發(fā)生的所有事件,我們一直在用,而且從DOM的很早的版本就一直在用著。早期的網(wǎng)景(后來(lái)的火狐)和IE...

    SimonMa 評(píng)論0 收藏0
  • 整理DOM事件相關(guān)知識(shí)點(diǎn)

    摘要:事件相關(guān)內(nèi)容當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí)如果希望去獲得用戶行為就需要借助事件來(lái)完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識(shí)如下這也是面試中遇到的問(wèn)題事件的級(jí)別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對(duì)象常見的 DOM事件相關(guān)內(nèi)容 當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí), 如果希望去獲得用戶行為, 就需要借助事件來(lái)完成. 事件部分內(nèi)容在 JS中重要性不言而喻. ...

    shenhualong 評(píng)論0 收藏0
  • 整理DOM事件相關(guān)知識(shí)點(diǎn)

    摘要:事件相關(guān)內(nèi)容當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí)如果希望去獲得用戶行為就需要借助事件來(lái)完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識(shí)如下這也是面試中遇到的問(wèn)題事件的級(jí)別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對(duì)象常見的 DOM事件相關(guān)內(nèi)容 當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí), 如果希望去獲得用戶行為, 就需要借助事件來(lái)完成. 事件部分內(nèi)容在 JS中重要性不言而喻. ...

    red_bricks 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<