溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript事件委托的示例分析

發(fā)布時間:2020-12-03 09:35:38 來源:億速云 閱讀:160 作者:小新 欄目:web開發(fā)

這篇文章主要介紹JavaScript事件委托的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

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

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

某公司有三位員工,他們的快遞收件地址為公司,每當有快遞送達時,快遞員撥打其電話進行通知,他們接到電話后去取件。

員工ID員工名稱聯(lián)系方式
A111111
B222222
C333333

對應到頁面,就是每個員工是一個標記:

<ul id="前臺工作人員">
    <li id="A">員工甲</li>
    <li id="B">員工乙</li>
    <li id="C">員工丙</li>
</ul>

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

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

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

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

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

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

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

<ul id="前臺工作人員">
    <li id="A">員工甲</li>
    <li id="B">員工乙</li>
    <li id="C">員工丙</li>
</ul>

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

假設(shè)此時快遞員打電話通知員工甲取件(onclick),但員工甲的DOM節(jié)點<li>并無對應事件(onclick),所以這個事件會“冒泡”到<li>的父元素<ul>,發(fā)現(xiàn)<ul>上有onclick處理事件,于是觸發(fā)該事件,由前臺工作人員收取快遞。

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

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

例如,當新員工丁來到公司后:

...
<input type="button" id="btn" value="添加新員工">
...

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

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

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

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

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

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

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

答案是肯定的。

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

  • 員工甲因為便宜,喜歡使用申通快遞,申通只送到園區(qū)大門;
  • 員工乙是京東會員,總是購買京東自營商品,京東快遞送到樓下;
  • 員工丙是順豐VIP,順豐快遞會送到送到所在樓層大廳。

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

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操作,而且為每一個對應節(jié)點都設(shè)置了事件函數(shù)。

而若采用事件委托:

var aUl = document.getElemengtByID("前臺工作人員");
aUl.onclick = function (ev) {
    var target = ev || window.event; /*兼容瀏覽器*/
    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)進行,可以有效提升網(wǎng)頁性能。

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

事件冒泡

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

以上是“JavaScript事件委托的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI