Vanilla JS event delegation - dealing with child elements of the target element

前端 未结 2 1715
挽巷
挽巷 2020-11-28 09:35

I\'m trying to do event delegation in vanilla JS. I have a button inside a container like this

2条回答
  •  天涯浪人
    2020-11-28 09:50

    Newer browsers

    Newer browsers support .matches:

    this.container.addEventListener('click', function(e){
        if (e.target.matches('#game-again,#game-again *')) {
            e.stopPropagation();
            self.publish('primo:evento');
        }
    });
    

    You can get the unprefixed version with

    var matches = document.body.matchesSelector || document.body.webkitMatchesSelector || document.body.mozMatchesSelector || document.body.msMatchesSelector || document.body.webkitMatchesSelector
    

    And then use .apply for more browsers (Still IE9+).

    Older browsers

    Assuming you have to support older browsers, you can walk up the DOM:

    function hasInParents(el,id){
        if(el.id === id) return true; // the element
        if(el.parentNode) return hasInParents(el.parentNode,id); // a parent
        return false; // not the element nor its parents
    }
    

    However, this will climb the whole dom, and you want to stop at the delegation target:

    function hasInParentsUntil(el,id,limit){
        if(el.id === id) return true; // the element
        if(el === limit) return false;
        if(element.parentNode) return hasInParents(el.parentNode,id); // a parent
        return false; // not the element nor its parents
    }
    

    Which, would make your code:

    this.container.addEventListener('click', function(e){
        if (hasInParentsUntil(e.target,'game-again',container)) { // container should be 
            e.stopPropagation();                                  // available for this
            self.publish('primo:evento');
        }
    });
    

提交回复
热议问题