成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一個(gè)案例讀懂JS事件委托

ad6623 / 2932人閱讀

摘要:網(wǎng)上有關(guān)于事件委托的一個(gè)取快遞例子,十分生動(dòng),這里我對(duì)它作一些修改和拓展,然后通過程序來說明事件委托的機(jī)制。還有一個(gè)優(yōu)點(diǎn)當(dāng)增加新的節(jié)點(diǎn)時(shí),自動(dòng)攜帶父元素的事件效果。以上便是事件委托的基本思想。與其對(duì)應(yīng)的還有事件捕獲。

事件委托(又名事件代理),就是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。

網(wǎng)上有關(guān)于事件委托的一個(gè)“取快遞”例子,十分生動(dòng),這里我對(duì)它作一些修改和拓展,然后通過程序來說明事件委托的機(jī)制。

某公司有三位員工,他們的快遞收件地址為公司,每當(dāng)有快遞送達(dá)時(shí),快遞員撥打其電話進(jìn)行通知,他們接到電話后去取件。

員工ID 員工名稱 聯(lián)系方式
A 111111
B 222222
C 333333

對(duì)應(yīng)到頁(yè)面,就是每個(gè)員工是一個(gè)標(biāo)記:

  • 員工甲
  • 員工乙
  • 員工丙

每位員工接電話取快遞的行為就是一個(gè)個(gè)事件,這里我們假設(shè)收取快遞行為對(duì)應(yīng)著onclick事件:

A.onclik = function() {
    收取快遞;
};
B.onclick = function() {
    收取快遞;
};
C.onclick = function() {
    收取快遞;
};

以上的實(shí)現(xiàn),通常為通過循環(huán)遍歷每一個(gè)員工,為其增加事件:

/*程序1*/
var aUl = document.getElemengtByID("前臺(tái)工作人員");
var aLi = aUl.getElemengtsByTagName("li");
for (var i = 0; i < aLi.length; i++) {
    aLi[i].onclick = function() {
        收取快遞;
    }
}

可以看到,為每個(gè)員工都設(shè)置一個(gè)事件,會(huì)產(chǎn)生冗余代碼,占用內(nèi)存,同時(shí)會(huì)進(jìn)行多次DOM操作(與DOM節(jié)點(diǎn)進(jìn)行交互),影響頁(yè)面運(yùn)行性能。

“減少DOM操作是性能優(yōu)化的主要思想之一”

于是,我們理所當(dāng)然地想到:為什么不能讓前臺(tái)工作人員幫我們簽收快遞呢?

  • 員工甲
  • 員工乙
  • 員工丙
/*程序2*/ var tel = document.getElementById("前臺(tái)工作人員"); tel.onclick = function() { 收取快遞; }

假設(shè)此時(shí)快遞員打電話通知員工甲取件(onclick),但員工甲的DOM節(jié)點(diǎn)

  • 并無對(duì)應(yīng)事件(onclick),所以這個(gè)事件會(huì)“冒泡”到
  • 的父元素
      ,發(fā)現(xiàn)
        上有onclick處理事件,于是觸發(fā)該事件,由前臺(tái)工作人員收取快遞。

        可以看到,這樣一來,不僅縮減代碼量,同時(shí)與DOM節(jié)點(diǎn)的交互次數(shù)也得到了縮減。

        還有一個(gè)優(yōu)點(diǎn):當(dāng)增加新的DOM節(jié)點(diǎn)時(shí),自動(dòng)攜帶父元素的事件效果。也就是說,當(dāng)有一個(gè)新員工丁來公司后,前臺(tái)工作人員會(huì)直接幫他收取快遞,而無需專門為他設(shè)置事件。

        例如,當(dāng)新員工丁來到公司后:

        ...
        
        ...
        
        ...
        /*程序3*/
        var aBtn = document.getElementById("btn");
        aBtn.onclick = function() {
            var aLi = document.createElement("li");
            oLi.innerHTML = "員工丁";
            aUl.appendChild(aLi);
        }
        ...
        
        

        在不使用事件委托的程序中,新增的員工丁是沒有事件的,我們需要用一個(gè)函數(shù)包含住程序1:

        /*程序4*/
        function pro1() {
            var aUl = document.getElemengtByID("前臺(tái)工作人員");
            var aLi = aUl.getElemengtsByTagName("li");
            for (var i = 0; i < aLi.length; i++) {
                aLi[i].onclick = function() {
                    收取快遞;
                }
            }
        }
        

        然后在新增新員工丁的程序的末尾執(zhí)行這個(gè)函數(shù):

        /*程序5*/
        var aBtn = document.getElementById("btn");
        aBtn.onclick = function() {
            ...
            pro1();
        }
        

        這樣做的缺點(diǎn)是顯而易見的:DOM節(jié)點(diǎn)交互次數(shù)成倍增加。
        若我們采用事件委托機(jī)制來實(shí)現(xiàn),就不會(huì)存在這個(gè)問題,子元素節(jié)點(diǎn)的onclick事件會(huì)直接在父元素節(jié)點(diǎn)得到執(zhí)行。

        到這里,我們會(huì)想到:對(duì)于同一種事件來說,使用事件委托將其放置在父元素節(jié)點(diǎn)上固然很方便。但如果對(duì)于不同的子元素節(jié)點(diǎn)要執(zhí)行不同的事件呢,還能使用事件委托嗎?

        答案是肯定的。

        例如上述三位公司員工,總是使用固定品牌的快遞:

        員工甲因?yàn)楸阋耍矚g使用申通快遞,申通只送到園區(qū)大門;

        員工乙是京東會(huì)員,總是購(gòu)買京東自營(yíng)商品,京東快遞送到樓下;

        員工丙是順豐VIP,順豐快遞會(huì)送到送到所在樓層大廳。

        他們?nèi)辉诮拥诫娫捄?,前臺(tái)工作人員需要去不同的地方取件,對(duì)于不使用事件委托的程序,需要對(duì)每個(gè)人設(shè)置獨(dú)特的處理事件:

        var A = document.getElementById("A");
        var B = document.getElementById("B");
        var C = document.getElementById("C");
        
        A.onclick = function() {
            去園區(qū)大門取快遞;
        }
        B.onclick = function() {
            去樓下取快遞;
        }
        C.onclick = function() {
            去本層大廳取快遞;
        }
        

        至少需要三次DOM操作,而且為每一個(gè)對(duì)應(yīng)節(jié)點(diǎn)都設(shè)置了事件函數(shù)。

        而若采用事件委托:

        var aUl = document.getElementByID("前臺(tái)工作人員");
        aUl.onclick = function (ev) {
            var target = ev.target || ev.srcElement; /*兼容瀏覽器*/
            if (target.nodeName.toLocaleLowerCase() == "li") {
                switch(target.id) {
                    case "A" :
                        去園區(qū)大門取快遞;
                        break;
                    case "B" :
                        去樓下取快遞;
                        break;
                    case "C" :
                        去本層大廳取快遞;
                        break;
                }
            }
        }
        

        這樣一來,DOM操作就只有一次,其他的操作都在JS內(nèi)進(jìn)行,可以有效提升網(wǎng)頁(yè)性能。

        以上便是JS事件委托的基本思想。簡(jiǎn)而言之,就是利用事件冒泡這一特點(diǎn),來對(duì)事件進(jìn)行管理,減少冗余代碼,減少不必要的創(chuàng)建,減少交互操作以節(jié)約內(nèi)存和提高性能。

        事件冒泡

        事件冒泡是當(dāng)觸發(fā)某個(gè)DOM元素節(jié)點(diǎn)時(shí),若該節(jié)點(diǎn)沒有對(duì)應(yīng)事件,則檢查其父元素是否有對(duì)應(yīng)事件,若有,則執(zhí)行,若沒有,繼續(xù)向上檢查。與其對(duì)應(yīng)的還有事件捕獲。

        關(guān)于事件流的具體分析,將在以后的文章中總結(jié)。

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

    轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102543.html

    相關(guān)文章

    • Javascript事件

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

      baiy 評(píng)論0 收藏0
    • Javascript事件

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

      luffyZh 評(píng)論0 收藏0
    • Javascript事件

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

      pcChao 評(píng)論0 收藏0
    • 百度網(wǎng)盤文件夾框選功能

      摘要:案例說明使用原生完成桌面操作級(jí)應(yīng)用,對(duì)于原生的掌握情況而言,是一個(gè)較為全面的綜合型案例。本次課從事件相關(guān)的功能入手,給大家?guī)碓敿?xì)的分享。 showImg(https://segmentfault.com/img/bVbh1qw); 案例說明:使用原生 JS 完成桌面操作級(jí)應(yīng)用,對(duì)于原生 JS 的掌握情況而言,是一個(gè)較為全面的綜合型案例。本次課從事件(event)相關(guān)的功能入手,給大家...

      jkyin 評(píng)論0 收藏0
    • 【重溫基礎(chǔ)】20.事件

      摘要:本文是重溫基礎(chǔ)系列文章的第二十篇。事件捕獲為截獲事件提供機(jī)會(huì),然后實(shí)際的目標(biāo)接收到事件,最后事件冒泡,對(duì)事件作出響應(yīng)。事件處理事件處理,即響應(yīng)某個(gè)事件。包括導(dǎo)致事件的元素事件類型等其他信息。 本文是 重溫基礎(chǔ) 系列文章的第二十篇。 這是第三個(gè)基礎(chǔ)系列的第一篇,歡迎持續(xù)關(guān)注呀! 重溫基礎(chǔ) 系列的【初級(jí)】和【中級(jí)】的文章,已經(jīng)統(tǒng)一整理到我的【Cute-JavaScript】的Java...

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

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

    0條評(píng)論

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