首页 文章

NodeList上的addEventListener

提问于
浏览
21

NodeList是否支持addEventListener . 如果不是,将EventListener添加到NodeList的所有节点的最佳方法是什么 . 目前我正在使用下面显示的代码段,是否有更好的方法来执行此操作 .

var ar_coins = document.getElementsByClassName('coins');
for(var xx=0;xx < ar_coins.length;xx++)
{
        ar_coins.item(xx).addEventListener('dragstart',handleDragStart,false);
}

7 回答

  • 0

    在es6中,你可以使用Array.from从nodelist做一个数组 .

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

    或者只使用箭头功能

    Array
      .from(ar_coins)
      .forEach(element => element.addEventListener('click', callback))
    
  • 10

    没有循环遍历每个元素就没有办法做到这一点 . 当然,您可以编写一个函数来为您完成 .

    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);
    

    或更专业的版本:

    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);
    

    而且,虽然你没有问过jQuery,但这是jQuery特别擅长的东西:

    $('.coins').on('dragstart', handleDragStart);
    
  • 4

    实际上有一种没有循环的方法:

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

    这种方式用于我的一个单行助手库 - nanoQuery .

  • 13

    我能想到的最好的是:

    const $coins = document.querySelectorAll('.coins')
    [...$coins].forEach($coin => $coin.addEventListener('dragstart', handleDragStart));
    

    请注意,这使用了ES6功能,因此请务必首先进行转换!

  • 4

    最简单的例子是将此功能添加到 NodeList

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

    现在你可以这样做:

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

    以同样的方式,你可以做一个 forEach 循环

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

    使用:

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

    EDIT :请注意,自2016年11月起,NodeList.prototype.forEach已经存在于FF中 . 虽然没有IE支持

  • 27

    我想另一种选择是使用 Object.definePropertyNodeList 上定义 addEventListener . 这样您可以像处理单个节点一样处理NodeList .

    举个例子,我在这里创建了一个jsfiddle:http://jsfiddle.net/2LQbe/

    关键是这个:

    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;
        }
    });
    
  • 1

    您也可以使用原型设计

    NodeList.prototype.addEventListener = function (type, callback) {
        this.forEach(function (node) {
            node.addEventListener(type, callback);
        });
    };
    

相关问题