事件捕獲、事件冒泡、事件委託(代理)

事件捕獲:事件從最不精確的對象(document對象)開始觸發,然後到最精確

事件冒泡:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發

不是所有事件都能冒泡。以下事件不冒泡:blur、focus、load、unload(關閉頁面)

事件委託(代理):不在事件的發生地(直接dom)上設置監聽函數,而是在其父元素上設置監聽函數,通過事件冒泡,父元素可以監聽到子元素上事件的觸發,通過判斷事件發生元素DOM的類型,來做出不同的響應。

爲什麼要用事件委託:

在JavaScript中,添加到頁面上的事件處理程序數量將直接關係到頁面的整體運行性能,因爲需要不斷的與dom節點進行交互,訪問dom的次數越多,引起瀏覽器重繪與重排的次數也就越多,就會延長整個頁面的交互就緒時間,這就是爲什麼性能優化的主要思想之一就是減少DOM操作的原因;如果要用事件委託,就會將所有的操作放到js程序裏面,與dom的操作就只需要交互一次,這樣就能大大的減少與dom的交互次數,提高性能;

事件委託怎麼實現:

舉例:最經典的就是ul和li標籤的事件監聽,比如我們在添加事件時候,採用事件委託機制,不會在li標籤上直接添加,而是在ul父元素上添加。

**好處:**比較合適動態元素的綁定,新添加的子元素也會有監聽函數,也可以有事件觸發機制。

// 通用的事件綁定函數
function bindEvent(elem, type, selector, fn) {
    if (fn = null) {
        fn = selector;
        selector = null;
    }
    elem.addEventListener(type, function(e){
        var target;
        if (selector) {
            target = e.target;
            // matches 用來判斷當前DOM節點能否完全匹配對應的CSS選擇器規則;
            // 如果匹配成功,返回true,反之則返回false。
            if (target.matches(selector)) {
                fn.call(target, e);
            }
        } else {
            fn(e);
        }
    })
}

// 使用代理
var div1 = document.getElementById('div1');
bindEvent(div1, 'click', 'a', function(e){
    console.log(this.innerHtml);
})
// 不使用代理
var a = document.getElementById('a1');
bindEvent(a, 'click', function(e){
    console.log(a.innerHtml);
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章