Skip to content Skip to sidebar Skip to footer

Javascript Event Delegation - Behavior

I'm trying to create web-page, and to improve performance, I decide to use event delegation, instead of direct binding, but I came across with strange behavior of event delegation

Solution 1:

Once you handled the click, you can walk the visual tree, starting from the target, to find the information you need. You might seek by type (node name), by tag, ... for the sake of the example, i just seek on element up to get a 'data-link' attribute if i don't find one on the target, but you have many choices here.

Edit : another idea is to use event.currentTarget, to get the element on which you hooked the event.

The updated fiddle will print :

delegate call on h1 or p of section1

when you click on h1 or p1

and it will print :

delegate section 1

when you click on the whole section.

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

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

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

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

Rq : i didn't get why you hook the event on the parent of the element, might be simpler not to do it. :-)

Solution 2:

I found the solution with CSSpointer-events

jsFiddle with CSS


.myClass * {
    pointer-events: none;
}

or with JavaScript

jsFiddle with JavaScript


(function () {
    "use strict";

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

    delegate(ele);

    functiondelegate(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"));
            }
        });
    }
}());

Solution 3:

Add the event listener to ele instead of ele.parentNode, and use this instead of e.target.

Demo

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

Be aware that e.target is the element the event was dispatched on. But in your case you don't want that, you want the element which has the event handler, so use this (or ele).

Post a Comment for "Javascript Event Delegation - Behavior"