JavaScript中的事件代理

概念:

  • JavaScript高級(jí)程序設(shè)計(jì) (簡稱JS高程) :事件代理 (事件委托) 利用了事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。

作用:

  1. 減少與dom的交互次數(shù),提高代碼性能。 (--代碼性能--)

    • 在JavaScript中,添加到頁面上的事件處理程序數(shù)量將直接關(guān)系到頁面的整體運(yùn)行性能,因?yàn)樾枰粩嗟呐cdom節(jié)點(diǎn)進(jìn)行交互,訪問dom的次數(shù)越多,引起瀏覽器重繪與重排的次數(shù)也就越多,就會(huì)延長整個(gè)頁面的交互就緒時(shí)間,這就是為什么性能優(yōu)化的主要思想之一就是要減少DOM操作;如果使用事件代理,就會(huì)將所有的操作放到j(luò)s程序里面,與dom的操作就只需要交互一次,這樣就能大大的減少與dom的交互次數(shù),提高性能。
    • JS高程上關(guān)于代碼優(yōu)化中提到了:如果可能,在文檔級(jí)別附加事件處理程序,這樣可以處理整個(gè)頁面的事件。
  2. 動(dòng)態(tài)生成DOM元素時(shí),可通過事件代理給新增的元素添加事件函數(shù)。

    • 比如在異步獲取后臺(tái)數(shù)據(jù)加載頁面時(shí),直接給動(dòng)態(tài)生成的DOM元素綁定事件函數(shù)可能需要在ajax交互時(shí)加入事件函數(shù),這樣往往會(huì)使得代碼變得混亂,而使用事件代理則會(huì)非常方便。

原理:

  • 事件冒泡:事件開始時(shí)由嵌套層次最深的節(jié)點(diǎn)開始接收,然后逐級(jí)向其父級(jí)節(jié)點(diǎn)傳播。
    • 例:頁面中有 div>ul>li>p 的結(jié)構(gòu),當(dāng)你 click 了 p 元素,click 事件首先在 p 元素上發(fā)生,然后,click 事件沿DOM樹向上傳播,分別在 li>ul>div 上發(fā)生,按照J(rèn)S高程上的說明,最終會(huì)傳播到 document 對(duì)象。
    • 注:與事件冒泡對(duì)應(yīng)的還有事件捕獲。
  • 事件代理:利用事件冒泡原理,把事件函數(shù)綁定在父級(jí)元素上,再指定需要執(zhí)行函數(shù)的子元素執(zhí)行事件函數(shù);在觸發(fā)事件時(shí),事件會(huì)依次冒泡到父級(jí)元素,從而觸發(fā)綁定在父級(jí)元素的事件函數(shù)。
    • 對(duì)于事件代理原理的理解,閱讀下面關(guān)于事件對(duì)象和具體用法的介紹后會(huì)更加清晰。

用法:

1.原生JS

  • 事件對(duì)象:在觸發(fā)DOM上的某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象 event,這個(gè)對(duì)象中包含著所有與事件有關(guān)的信息,在執(zhí)行事件處理程序時(shí) event 對(duì)象會(huì)被傳入;只有在事件處理程序執(zhí)行期間,event 對(duì)象才會(huì)存在;一旦事件處理程序執(zhí)行完成,event 對(duì)象就會(huì)被銷毀;對(duì)于事件代理,這里重點(diǎn)介紹下 event 的幾個(gè)屬性。

    • currentTarget :其事件函數(shù)當(dāng)前正在處理事件的那個(gè)元素;如果感覺這個(gè)定義有點(diǎn)拗口,你可以暫且把 currentTarget 簡單的理解為原生JS中事件函數(shù)內(nèi)部的 this 。
    • target :事件目標(biāo);即觸發(fā)事件的實(shí)際目標(biāo)。
    • 這里用一個(gè)例子說明:假設(shè)頁面中有 ul>li>p 的結(jié)構(gòu),然后點(diǎn)擊 p 標(biāo)簽來執(zhí)行下面代碼(這里為方便閱讀沒有做兼容性處理,此代碼需要在chrome瀏覽器下運(yùn)行)
    var ul = document.querySelector('ul');
    var li = document.querySelector('li');
    var p = document.querySelector('p');
    
    ul.onclick = function(event) {
        console.log(this);  // <ul>...</ul>
        console.log(event.currentTarget);   // <ul>...</ul>
        console.log(event.target);  // <p>...</p>
    }
    

    從運(yùn)行結(jié)果可以看到,當(dāng)把事件函數(shù)綁定在父元素時(shí),currentTarget 屬性和函數(shù)內(nèi)部的 this 都為綁定事件函數(shù)的父元素,而 target 屬性的值則是我們想要觸發(fā)事件的子元素。

  • 具體用法:給父元素綁定事件函數(shù),然后通過條件判斷找到需要執(zhí)行事件函數(shù)的元素。

頁面結(jié)構(gòu)如下:

<ul>
    <li><p id="aaa">AAA</p></li>
    <li><p id="bbb">BBB</p></li>
</ul>

JS代碼如下:

var ul = document.querySelector('ul');
var li = document.querySelector('li');
var p = document.querySelector('p');

ul.onclick = function(e) {
    // 兼容性處理
    var e = e || window.event;
    var target = e.target || e.srcElement;

    switch (target.id){
        case "aaa":
            alert("AAA");
            break;
        case "bbb":
            alert("BBB");
            break;
        default :
            alert("未點(diǎn)擊 p 標(biāo)簽");
            break;
    }
}

從測(cè)試結(jié)果可以看到,只在父元素上綁定一次事件函數(shù),通過條件判斷可以分別找到父元素下觸發(fā)事件的子元素,然后分別進(jìn)行操作。

2.jQuery

  • jQuery 的 on 方法中已經(jīng)封裝好了事件代理的功能,而且事件函數(shù)內(nèi)部的 this 直接指向的就是被指定的元素。
// on 的3個(gè)參數(shù) 1.事件類型 2.給事件指定的元素 3.事件函數(shù)
    $("div").on("click", "p", function () {
        alert("p");
        console.log(this);  // p
    })

注意 jQuery 的 on 方法中 this 直接指向的就是觸發(fā)事件的子元素 p 。

結(jié)尾:

  • 原生JS中的一些事件如 onmouseover 存在一些不好用的問題,同時(shí)通過 target 等屬性進(jìn)行篩選又需要寫不少條件判斷的代碼,相比下jQuery 的 on 方法則封裝得簡單直接,但是這里并非單純推薦使用第三方庫,實(shí)際應(yīng)用中要根據(jù)具體需求做選擇。

會(huì)同步在 kabumie 的 github 空間上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 總結(jié): 鼠標(biāo)事件 1.click與dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r閱讀 1,639評(píng)論 2 10
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,363評(píng)論 0 8
  • 1.背景介紹 1.1什么是事件委托? 事件委托還有一個(gè)名字叫事件代理,JavaScript高級(jí)程序設(shè)計(jì)上講:事件委...
    我叫于搞吧閱讀 1,672評(píng)論 4 9
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,367評(píng)論 0 2
  • “你家孩子這次考了多少?” “你家孩子在哪補(bǔ)習(xí)呀?” “我家寶貝,古箏彈得跟老師一樣” …… 諸如此類,覆蓋有“教...
    常五閱讀 236評(píng)論 0 0