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

資訊專欄INFORMATION COLUMN

事件委托和冒泡機制有關系嗎?

joywek / 1001人閱讀

摘要:等等,挺在這里,雖然不僅一篇文章闡述了事件委托是利用了冒泡機制,得益于冒泡機制,但是,怎么得益的,怎么利用的。事件委托和冒泡機制有關系嗎接下來我想引出本文的重點事件委托和冒泡機制有關系嗎我認為就算有關系,關系也不大。

面試官提出的問題

我們在面試前端的過程中,經常會聽到面試官問這樣的問題:

  

如果我有一個頁面,里面1000個元素都要綁定click事件,請問你要怎么做

如果你回答逐個綁定那估計可以直接回家了,面試官希望的答案是你來高談闊論事件委托,你應該能給出方法并寫出解決方案。
接下來,考官一定要問,這么做的好處是什么,或者你為什么用事件委托。

我認為好處主要有兩個:

事件只需要綁定一次,而不是綁定1000次,提高效率

動態添加進父級的元素自動擁有事件

根據http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/ 更專業的說法如下:

Fewer functions to manage. 管理較少的函數

Takes up less memory. 更少的內存消耗

Fewer ties between your code and the DOM.降低代碼和dom之間的關聯

Don’t need to worry about removing event handlers when changing the DOM via修改dom的時候不用考慮刪除事件。

這還沒完,面試官通常會接下來問,那么,你綁定在父級上,頁面怎么知道你點擊的是哪一個?

我想這應該回答,利用了事件的冒泡機制。

等等,挺在這里,雖然不僅一篇文章闡述了事件委托是利用了冒泡機制,得益于冒泡機制,但是,怎么得益的,怎么利用的。

于是好奇的我引申出另外一個復雜的議題,事件的綁定和執行機制。

事件執行

很多文章里介紹了這個機制,這篇文章很簡明詳盡:
http://www.quirksmode.org/js/events_order.html

概括一下,就是由于歷史原因,瀏覽器對事件的處理有兩種模式,一種是先執行外面父級元素的事件(捕獲模式 capturing),一種先執行內部元素的事件(冒泡模式bubbling)。這個概念就類似圖層,一種是外面的在前面,另一種是里面在前面。

現代瀏覽器里參照w3c規范,采用了這兩種方式并行的方式,簡單的來說就是先捕獲,再冒泡。(為什么,為什么,規定為一種不好么)

我們都知道為某個元素注冊事件,是通過addEventListener這個方法,那么,我直接注冊的事件,他是屬于捕獲執行呢,還是冒泡執行呢?還是說我捕獲階段執行一次,冒泡階段再執行一次。難道說每次都執行兩次?

不對,同樣一次綁定的方法是執行一次,因為它要么屬于捕獲階段,要么屬于冒泡階段。這兩個階段就像通向公司的兩條路,你去公司是一條路,回來是另外一條路,你的事件是路上的小賣鋪,它要么在去的那條路上,要么在回來的那條路上。當然你也可以兩條路上都開一家小賣鋪,雖說沒什么意義,但是這樣事件觸發的時候確實執行了兩次,不過這也能證明事件執行的兩個階段。

事件執行順序的實驗

先忘掉上面的理論,下面我們來做個試驗,記住下面的html,我們打算為out同時綁定兩個事件,看看執行順序是怎么樣的

Click
var a = document.querySelector("div#out")
var b = document.querySelector("div#inner1")

a.addEventListener("click",function(e){
   alert(e.target+"事件A")
})
a.addEventListener("click",function(e){
   alert(e.target+"事件B") 
})

我們可以看到,為同一個元素先后綁定兩個事件,執行的順序是從上到下的,把事件B提到A前面就會先執行B。

接下來我們試一下通過addEventListener第三個參數指定事件綁定在哪條路上,false為冒泡階段,true為捕獲階段。

a.addEventListener("click",function(e){
    alert(e.target+"外部元素在冒泡階段")
},false)

a.addEventListener("click",function(e){
    alert(e.target+"外部元素在捕獲階段")
},true)

這下我們可以看到,不論冒泡在前面還是后面,都是先執行捕獲階段的那行代碼,佐證了先前說道的w3c規范下的先執行捕獲再執行冒泡的行為。

不過在這里的實驗中,我無意發現了一個有趣的現象,當你把html改成沒有子元素,比如

Click

這時候就不遵循先捕獲再冒泡的原則了,看起來像是判斷節點沒有子元素,就不需要使用捕獲和冒泡的流程,只采用先來后到的順序。這其中的原理還望高手指教。

總結: 當一個頁面元素包含子元素節點的時候,他在處理在其身上的綁定事件的時候,采用先執行捕獲階段的事件,再執行冒泡階段的事件。而事件處于哪個階段,是由addevnetlistener的第三個參數決定的。

阻止冒泡

我們都知道,阻止冒泡是采用類似 stopPropagation()的方法。但是請考慮這樣一個問題:

a.addEventListener("click",function(e){
    alert(e.target+"外部元素在冒泡階段")
},false)
a.addEventListener("click",function(e){
    alert(e.target+"外部元素在捕獲階段")
},true)

b.addEventListener("click",function(e){
    e.stopPropagation()
    alert(e.target+"內部元素上的事件")
})

這段代碼里,我點擊b,事件觸發的順序是怎樣的?
答案是:外部元素捕獲 ---> 內部元素事件

因為捕獲是永遠優先執行的,內部元素由于不存在子元素,所以只有一個階段,無所謂先執行后執行,由于自身沒有冒泡事件,所以stoppropagation() 掠過自身,尋找父級的冒泡階段上的事件,一次查找,全部給阻止掉。

所以,想要點擊內部的時候無視外部事件,一定不要把外部的事件放在捕獲階段,就是說第三個參數不要設為true。

我們再把代碼搞更復雜一些:

click
var a = document.querySelector("div#out")
var b = document.querySelector("div#inner1")
var c = document.querySelector("div#inner2")

a.addEventListener("click",function(e){
    alert("a在冒泡階段") 
},false)
a.addEventListener("click",function(e){
    alert("a在捕獲階段")
},true)

b.addEventListener("click",function(e){
    alert("b在冒泡階段")
},false)
b.addEventListener("click",function(e){
    alert("b在捕獲階段")
},true)

c.addEventListener("click",function(e){
    alert(e.target+"內部元素事件")
})

執行一遍,可以加深了對事件這個模式的理解,順序是這樣的

a捕獲 ---> b捕獲 ---> 內部事件 ---> b冒泡 ---> a冒泡

這里我感興趣的是阻止冒泡會怎么樣,測下來是,如果把stoppropagation() 放在b,b本身的冒泡還是會執行,那么同理如果放在c,c本身如果有冒泡事件也會執行,

所以stoppropagation()所做的事情可以這么理解,阻止父級元素冒泡階段的事件。

事件委托和冒泡機制有關系嗎?

接下來我想引出本文的重點:事件委托和冒泡機制有關系嗎?
我認為就算有關系,關系也不大。

我們先來看一下一個常見的事件委托例子:

// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click",function(e) {
    // e.target is the clicked element!
    // If it was a list item
    if(e.target && e.target.nodeName == "LI") {
        // List item found!  Output the ID!
        console.log("List item ",e.target.id.replace("post-")," was clicked!");
    }
});

簡言之,綁定在父類上一個事件,然后通過回調函數的參數獲得當前點擊的是哪一個元素,相當于把事件綁定在子元素身上。

請問這跟上文長篇累牘的冒泡機制有什么聯系?

假設不存在冒泡或者捕獲,在父類上點擊到了子類或者不論點到哪,這個事件都是要執行的,子類這個元素還會作為引用傳到函數體里,我實在看不出這個冒泡有什么關系,如果要什么導致事件委托可以實現,應當是函數體內的引用才是

那么,這個引用是什么情況呢,繼續上面的實驗:

var a = document.querySelector("div#out")
var b = document.querySelector("div#inner1")
var c = document.querySelector("div#inner2")

a.addEventListener("click",function(e){
    alert("a在冒泡階段")
    console.log(e.target)//inner2
    console.log(this)//out
    console.log(e.currentTarget)//out
},false)
a.addEventListener("click",function(e){
    alert("a在捕獲階段")
    console.log(e.target)//inner2
},true)

b.addEventListener("click",function(e){
    alert("b在冒泡階段")
    console.log(e.target)//inner2
},false)
b.addEventListener("click",function(e){
    alert("b在捕獲階段")
    console.log(e.target)//inner2
},true)

c.addEventListener("click",function(e){
    alert(e.target+"內部元素事件")
    console.log(e.target)//inner2
})

我們能看到,不論在哪一層里,e.target都是你當前點擊的本身,這毫不奇怪,因為e本身是一個event對象,比如這里的MouseEvent,里面還帶了是否同時按下alt鍵,鼠標位置等信息,可見這個對象本身可以說是和綁定主體無關了,和事件有關。所以,和冒泡還是沒啥關系。以上代碼里還展示了兩種獲取事件執行主體的方法,分別是e.currentTarge 和 this

所以我的觀點是,雖然提到js的事件委托通常都會聯系到冒泡,但是就算當初沒有設計冒泡和捕獲,事件委托還是事件委托,它依賴的是event對象傳遞到監聽函數里面了,和其他無關。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/110066.html

相關文章

  • 有關Javascript的知識點

    摘要:事故起因因為這個如何阻止子元素繼承父元素事件,然后我只答出了自己知道的部分,對于我不知道,這里我把這些東西收集起來自己學習了,也方便他人參考。事件委托是怎么工作的事件委托和冒泡機制有關系嗎中使用與 事故起因: 因為這個jQuery如何阻止子元素繼承父元素事件?,然后我只答出了自己知道的部分,對于我不知道,這里我把這些東西收集起來.自己學習了,也方便他人參考。 Javascript ...

    verano 評論0 收藏0
  • JS專題之事件模型

    摘要:三事件流規定事件包括三個階段,事件捕獲,處于目標階段事件冒泡。一起來看添加新增加的,點擊發現沒有反應,說明事件沒有綁定進去,但是我們也并不想,每增加一個新元素,就為這個新元素綁定事件,重復低效率的工作應當避免去做。 本文共 1960 字,讀完只需 8 分鐘 事件 用戶與網頁交互是通過事件實現的,事件剛開始是作為分擔服務器負載的一個手段,起初沒有統一的規范,直到 DOM2 級,網景和 I...

    W4n9Hu1 評論0 收藏0
  • 事件冒泡機制委托機制

    摘要:二事件委托機制知道了事件的捕獲冒泡機制,我們可以利用它來實現更方便的程序控制,事件委托便是最典型的應用之一。下面來說說中的事件委托機制。 一、事件的捕獲與冒泡 ?? 由W3C規定的DOM2標準中,一次事件的完整過程包括三步:捕獲→執行目標元素的監聽函數→冒泡,在捕獲和冒泡階段,會依次檢查途徑的每個節點,如果該節點注冊了相應的監聽函數,則執行監聽函數。以下面的HTML結構為例: ...

    AprilJ 評論0 收藏0
  • 事件委托冒泡機制

    摘要:概念事件委托,就是某個事件本來該自己干的,但是自己不干,交給別人來干。冒泡機制,就是父節點監控著一塊區域的點擊事件,當點擊事件觸發時,會根據坐標來判斷是哪一塊區域被點擊,然后確定事件對象的屬性或者說是屬性。 概念 事件委托,就是某個事件本來該自己干的,但是自己不干,交給別人來干。就叫事件委托。打個比方:一個button對象,本來自己需要監控自身的點擊事件,但是自己不來監控這個點擊事...

    warmcheng 評論0 收藏0
  • javascript事件基礎知識

    摘要:可選,布爾值,指定事件是否在捕獲或冒泡階段執行,默認冒泡。適用范圍參數介紹必須,字符串,事件名稱。必須,指定事件觸發時執行的函數。事件冒泡事件冒泡與事件捕獲恰恰相反,事件冒泡順序是由內到外進行事件傳播,直到根節點。 什么是事件 javascript與HTML之間交互就是通過事件實現的,事件就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間。事件在瀏覽器中是以對象的形式存在的,即event,...

    ad6623 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<