簡體   English   中英

JavaScript事件委托-行為

[英]JavaScript Event Delegation - Behavior

我試圖創建網頁並提高性能,因此決定使用事件委托而不是直接綁定,但是遇到事件委托的奇怪行為,或者我錯過了某些事情...

這是我的HTML的結構

<div>
    <section class="myClass" data-link="section 1">
        <h1>Heading 1</h1>
        <p>Some text....</p>
    </section>
</div>

我想整節被點擊,但同時點擊h1p元素section event.target在那一刻是h1p ,而不是section ,所以表達的if語句失敗...

function delegate(ele) {
    ele.parentNode.addEventListener("click", function (e) {
        if (e.target.nodeName.toLowerCase() === "section" && e.target.classList.contains("myClass")) {
            console.log("delegate " + e.target.getAttribute("data-link"));
        }
    }, false);
}

我已經有了直接綁定的解決方案,但是與事件委派在同一結果中實現效果會更好。 這是jsFiddle

function direct(ele) {
    [].forEach.call(ele, function (value, index, array) {
        value.addEventListener("click", function(e) {
            console.log("direct " + value.getAttribute("data-link"));
        }, false);
    });
}

提前致謝!

處理完點擊之后,您可以從目標開始瀏覽視覺樹,以找到所需的信息。
為了示例,您可能按類型(節點名稱),按標記搜索... ...如果我在目標上找不到一個,則我只是在元素上搜索以獲得“數據鏈接”屬性,但是您在這里有很多選擇。

編輯:另一個想法是使用event.currentTarget,以獲取您在其上掛接事件的元素。

更新的小提琴將打印:

delegate call on h1 or p of section 1 

當您單擊h1或p1時

它會打印:

delegate section 1 

當您單擊整個部分時。

http://jsfiddle.net/KMJnA/4/

function delegate(ele) {
    ele.parentNode.addEventListener("click", delegateHandler, false);
}

function delegateHandler (e) {
    var target = e.target;  
    var attribute = target.getAttribute("data-link");
    // if target has no attribute
    // seek it on its parent
    if (!attribute) {
         attribute = target.parentNode.getAttribute("data-link");
    }

    if ( target.classList.contains("myClass") ) { 
         console.log("delegate " + attribute);
        } 
    else console.log('delegate call on h1 or p of ' + attribute);
}    

Rq:我不明白為什么將事件掛在元素的父元素上,不這樣做可能更簡單。 :-)

我找到了使用CSS 指針事件的解決方案

jsFiddle與CSS


.myClass * {
    pointer-events: none;
}

或使用JavaScript

jsFiddle與JavaScript


(function () {
    "use strict";

    var ele = document.querySelector(".myClass").parentNode;

    delegate(ele);

    function delegate(ele) {
        ele.addEventListener("click", function (e) {
            var target = e.target;

            while (!(target.nodeName.toLowerCase() === "section" && target.classList.contains("myClass"))) {
                target = target.parentNode;
                if (target === ele) {
                    break;
                }
            }

            if (target.nodeName.toLowerCase() === "section" && target.classList.contains("myClass")) {
                console.log("delegate " + target.getAttribute("data-link"));
            }
        });
    }
}());

將事件監聽器添加到ele而不是ele.parentNode ,並使用this代替e.target

演示

function delegate(ele) {
    ele.addEventListener("click", function (e) {
        if (this.nodeName.toLowerCase() === "section" && this.classList.contains("myClass")) {
            console.log("delegate " + this.getAttribute("data-link"));
        }
    }, false);
}

請注意, e.target是調度事件的元素。 但是,在您不想要的情況下,您需要具有事件處理程序的元素,因此請使用this (或ele )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM