addEventListener on NodeList

前端 未结 8 2080
轮回少年
轮回少年 2020-11-30 07:12

Does NodeList support addEventListener. If not what is the best way to add EventListener to all the nodes of the NodeList. Currently I am using the code snippet as show be

相关标签:
8条回答
  • 2020-11-30 07:47

    There is no way to do it without looping through every element. You could, of course, write a function to do it for you.

    function addEventListenerList(list, event, fn) {
        for (var i = 0, len = list.length; i < len; i++) {
            list[i].addEventListener(event, fn, false);
        }
    }
    
    var ar_coins = document.getElementsByClassName('coins');
    addEventListenerList(ar_coins, 'dragstart', handleDragStart); 
    

    or a more specialized version:

    function addEventListenerByClass(className, event, fn) {
        var list = document.getElementsByClassName(className);
        for (var i = 0, len = list.length; i < len; i++) {
            list[i].addEventListener(event, fn, false);
        }
    }
    
    addEventListenerByClass('coins', 'dragstart', handleDragStart); 
    

    And, though you didn't ask about jQuery, this is the kind of stuff that jQuery is particularly good at:

    $('.coins').on('dragstart', handleDragStart);
    
    0 讨论(0)
  • 2020-11-30 07:52

    in es6, you can do a array from nodelist, using Array.from, e.g.

    ar_coins = document.getElementsByClassName('coins');
    Array
     .from(ar_coins)
     .forEach(addEvent)
    
    function addEvent(element) {
      element.addEventListener('click', callback)
    }
    

    or just use arrow functions

    Array
      .from(ar_coins)
      .forEach(element => element.addEventListener('click', callback))
    
    0 讨论(0)
  • 2020-11-30 08:01

    There actually is a way to do this without a loop:

    [].forEach.call(nodeList,function(e){e.addEventListener('click',callback,false)})
    

    And this way is used in one of my one-liner helper libraries - nanoQuery.

    0 讨论(0)
  • 2020-11-30 08:02

    The simplest example is to add this functionality to NodeList

    NodeList.prototype.addEventListener = function (event_name, callback, useCapture)
    {
        for (var i = 0; i < this.length; i++)
        {
          this[i].addEventListener(event_name, callback, useCapture);
        }
    };
    

    Now you can do:

    document.querySelectorAll(".my-button").addEventListener("click", function ()
    {
        alert("Hi");
    });
    

    In the same way, you can do a forEach loop

    NodeList.prototype.forEach = function (callback)
    {
        for (var i = 0; i < this.length; i++)
        {
          callback(this[i], i);
        }
    };
    

    Using:

    document.querySelectorAll(".buttons").forEach(function (element, id)
    {
        input.addEventListener("change", function ()
        {
            alert("button: " + id);
        });
    });
    

    EDIT : note that NodeList.prototype.forEach has existed ever since november 2016 in FF. No IE support though

    0 讨论(0)
  • 2020-11-30 08:04

    I suppose another option would be to define addEventListener on NodeList using Object.defineProperty. That way you can treat the NodeList as you would a single Node.

    As an example, I created a jsfiddle here: http://jsfiddle.net/2LQbe/

    The key point is this:

    Object.defineProperty(NodeList.prototype, "addEventListener", {
        value: function (event, callback, useCapture) {
            useCapture = ( !! useCapture) | false;
            for (var i = 0; i < this.length; ++i) {
                if (this[i] instanceof Node) {
                    this[i].addEventListener(event, callback, useCapture);
                }
            }
            return this;
        }
    });
    
    0 讨论(0)
  • 2020-11-30 08:05

    You could also use prototyping

    NodeList.prototype.addEventListener = function (type, callback) {
        this.forEach(function (node) {
            node.addEventListener(type, callback);
        });
    };
    
    0 讨论(0)
提交回复
热议问题