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

資訊專欄INFORMATION COLUMN

DOM事件流與事件委托

chaos_G / 390人閱讀

摘要:事件流與事件委托事件,即文檔或?yàn)g覽器中發(fā)生的一些特定交互的瞬間,我們可以利用事件監(jiān)聽來預(yù)定事件,當(dāng)事件發(fā)生的時(shí)候執(zhí)行相應(yīng)的處理程序。本文主要討論事件流的三個(gè)階段,及利用事件委托機(jī)制進(jìn)行性能優(yōu)化。

事件流與事件委托

事件,即文檔或?yàn)g覽器中發(fā)生的一些特定交互的瞬間,我們可以利用事件監(jiān)聽來預(yù)定事件,當(dāng)事件發(fā)生的時(shí)候執(zhí)行相應(yīng)的處理程序。當(dāng)事件發(fā)生在某個(gè)DOM節(jié)點(diǎn)上時(shí),事件在DOM結(jié)構(gòu)中進(jìn)行一級一級的傳遞,這便形成了“流”,事件流便描述了從頁面中接收事件的順序。本文主要討論事件流的三個(gè)階段,及利用事件委托機(jī)制進(jìn)行性能優(yōu)化。

DOM事件流

關(guān)于事件流的理解,《JS高程三》中有個(gè)形象的比喻:

可以想象畫在一張紙上的一組同心圓,如果你把手指放在圓心上,那么你的手指指向的其實(shí)不是一個(gè)圓,而是紙上所有的圓。...>換句話說,在單擊按鈕的同時(shí),你也單擊了按鈕的容器元素,甚至也單擊了整個(gè)頁面。

————《JavaScript高級程序設(shè)計(jì)(第三版)》page 345

DOM2級事件中規(guī)定事件流包含3個(gè)階段:

捕獲階段

處于目標(biāo)階段

冒泡階段

首先發(fā)生的是事件捕獲階段,此時(shí)事件還沒有傳遞到目標(biāo)節(jié)點(diǎn)對象上,所以我們就有機(jī)會在這個(gè)階段進(jìn)行事件的截。然后是目標(biāo)節(jié)點(diǎn)接收到事件,最后是事件冒泡階段,可以在這個(gè)階段對事件做出處理和響應(yīng)。
我們先定義一段簡單的html結(jié)構(gòu):



  
    
  
  
      
事件捕獲階段

在事件捕獲階段中,先由不具體的節(jié)點(diǎn)(即上層節(jié)點(diǎn))接收到事件,然后一級一級往下傳遞,直到最具體的目標(biāo)節(jié)點(diǎn)接收到事件。
在DOM2級事件規(guī)范中,要求事件從document對象開始傳遞,但是諸如Chrome,F(xiàn)irefox等主流瀏覽器卻是從window開始傳遞的。

addEventListener方法的第三個(gè)參數(shù)是一個(gè)布爾值(可選),指定事件處理程序是否在捕獲或冒泡階段執(zhí)行。 當(dāng)為true時(shí),則事件處理程序?qū)⒃诓东@階段執(zhí)行。

誤區(qū):無論addEventListener的第三個(gè)參數(shù)是否為true,三個(gè)階段都會走一遍,這里的第三個(gè)參數(shù),指的是處理程序?qū)诓东@或者冒泡階段執(zhí)行,好比是你想買菜,你可以在上班路上,或者下班路上完成買菜,但無論什么時(shí)候買菜,你都要把這兩段路程走完。

document.querySelector("#btn").addEventListener("click", function () {
    console.log("btn was clicked");
},true);

document.querySelector("body").addEventListener("click", function () {
    console.log("body was clicked");
},true);

document.querySelector(".box").addEventListener("click", function () {
    console.log("box was clicked");
},true);

document.addEventListener("click", function () {
    console.log("document was clicked");
},true);

window.addEventListener("click", function () {
    console.log("window was clicked");
},true);

點(diǎn)擊click me按鈕后,控制臺依次打印出執(zhí)行結(jié)果:

window was clicked
document was clicked
body was clicked
box was clikced
btn was clicked

很明顯可以看出,在捕獲階段,事件由window對象開始,一級一級地向下傳遞,直到傳遞到最具體的button對象上。

事件冒泡階段

事件冒泡階段與捕獲階段恰好相反,冒泡階段是從最具體的目標(biāo)對象開始,一層一層地向上傳遞,直到window對象。
addEventListener方法默認(rèn)就是從冒泡階段執(zhí)行事件處理程序。

document.querySelector("#btn").addEventListener("click", function () {
    console.log("btn was clicked");
});

document.querySelector("body").addEventListener("click", function () {
    console.log("body was clicked");
});

document.querySelector(".box").addEventListener("click", function () {
    console.log("box was clicked");
});

document.addEventListener("click", function () {
    console.log("document was clicked");
});

window.addEventListener("click", function () {
    console.log("window was clicked");
});

點(diǎn)擊click me按鈕后,控制臺依次打印出執(zhí)行結(jié)果:

btn was clicked
box was clikced
body was clicked
document was clicked
window was clicked

上述過程示意圖:

阻止事件冒泡

我們可以使用event.stopPropagation()方法阻止事件冒泡過程,以防止事件冒泡而帶來不必要的錯(cuò)誤和困擾。
示例:

document.querySelector("#btn").addEventListener("click", function (event) {
    console.log("btn was clicked");
    event.stopPropagation();
});

document.querySelector("body").addEventListener("click", function () {
    console.log("body was clicked");
});

document.querySelector(".box").addEventListener("click", function () {
    console.log("box was clicked");
});

document.addEventListener("click", function () {
    console.log("document was clicked");
});

window.addEventListener("click", function () {
    console.log("window was clicked");
});

點(diǎn)擊click me按鈕后,控制臺打印出執(zhí)行結(jié)果顯示,事件沒有再向上冒泡傳遞給其他節(jié)點(diǎn)對象:

btn was clicked
事件委托

每個(gè)函數(shù)都是對象,都會占用內(nèi)存,所以當(dāng)我們的頁面中所包含的事件數(shù)量較多時(shí),如果給每個(gè)節(jié)點(diǎn)綁定一個(gè)事件,加上事件處理程序,就會造成性能很差。還有一個(gè)問題是,某個(gè)元素節(jié)點(diǎn)是后來通過JavaScript動(dòng)態(tài)添加進(jìn)頁面中的,這時(shí)候我們?nèi)绻崆皩λM(jìn)行綁定,但此時(shí)該元素并不存在,所以會綁定事件會失敗。解決上述兩個(gè)問題的一個(gè)常用方案,就是使用事件委托
舉例來說:

document.querySelector(".box").addEventListener(function (event) {
    switch (event.target.id) {
      case "btn":
        console.log("btn was clicked");
        break;
      case "btn-2":
        console.log("btn-2 was clicked");
        break;
      default:
        console.log("box was clicked");
        break;
    }
});
$(".box").append("");

簡單說,事件委托就是把本來該自己接收的事件委托給自己的上級(父級,祖父級等等)的某個(gè)節(jié)點(diǎn),讓自己的“長輩們”幫忙盯著,一旦有事件觸發(fā),再由“長輩們”告訴自己:“喂,孫子,有人找你~~”。
恩,差不多就是這么個(gè)意思,可憐天下父母心。

水平有限,歡迎大家不吝指正。

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

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

相關(guān)文章

  • 好文推薦:javascript: 事件委托解析

    摘要:前言之前不太明白事件委托。看了這個(gè)帖子,跟著代碼操作了一遍,終于明白了事件委托。推薦理由一步一步,漸進(jìn)式分析來說明事件委托。為簽收快遞,有兩種辦法一是三個(gè)人在公司門口等快遞二是委托給前臺代為簽收。 前言:之前不太明白事件委托。 看了這個(gè)帖子,跟著代碼操作了一遍,終于明白了事件委托。所以轉(zhuǎn)載。 推薦理由:一步一步,漸進(jìn)式分析來說明事件委托。 什么叫事件委托呢?它還有一個(gè)名字叫事件代理 ...

    Wuv1Up 評論0 收藏0
  • js 事件委托 事件代理

    摘要:事件委托事件代理高級程序設(shè)計(jì)上解釋事件委托就是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。事件委托原理事件委托是利用事件的冒泡原理來實(shí)現(xiàn)的,事件冒泡就是事件從最深的節(jié)點(diǎn)開始,然后逐級向上傳播事件。 js 事件委托 事件代理 JavaScript高級程序設(shè)計(jì)上解釋:事件委托就是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。 通過例子類比: 有...

    widuu 評論0 收藏0
  • Javascript事件

    摘要:見下圖更直觀在事件流中,事件的目標(biāo)在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個(gè)階段是目標(biāo)階段,于是事件在上發(fā)生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發(fā)生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個(gè)階...

    baiy 評論0 收藏0
  • Javascript事件

    摘要:見下圖更直觀在事件流中,事件的目標(biāo)在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個(gè)階段是目標(biāo)階段,于是事件在上發(fā)生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發(fā)生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個(gè)階...

    luffyZh 評論0 收藏0
  • Javascript事件

    摘要:見下圖更直觀在事件流中,事件的目標(biāo)在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個(gè)階段是目標(biāo)階段,于是事件在上發(fā)生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發(fā)生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個(gè)階...

    pcChao 評論0 收藏0

發(fā)表評論

0條評論

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