Javascript 节点列表上的addEventListener

Javascript 节点列表上的addEventListener,javascript,addeventlistener,nodelist,Javascript,Addeventlistener,Nodelist,NodeList是否支持addEventListener。如果不是,那么向NodeList的所有节点添加EventListener的最佳方法是什么。目前我正在使用如下所示的代码片段,是否有更好的方法来实现这一点 var ar_coins = document.getElementsByClassName('coins'); for(var xx=0;xx < ar_coins.length;xx++) { ar_coins.item(xx).addEventListener

NodeList是否支持addEventListener。如果不是,那么向NodeList的所有节点添加EventListener的最佳方法是什么。目前我正在使用如下所示的代码片段,是否有更好的方法来实现这一点

var ar_coins = document.getElementsByClassName('coins');
for(var xx=0;xx < ar_coins.length;xx++)
{
        ar_coins.item(xx).addEventListener('dragstart',handleDragStart,false);
}
var ar_coins=document.getElementsByClassName('coins');
对于(var xx=0;xx
如果不循环遍历每个元素,就无法完成此操作。当然,您可以编写一个函数来完成这项工作

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); 
实际上,有一种方法可以在没有循环的情况下做到这一点:


这种方法在我的一个单行助手库中使用-。

我想另一个选项是使用
对象定义
节点列表上的
addEventListener
。这样,您可以像对待单个节点一样对待节点列表

例如,我在这里创建了一个JSFIDLE:

关键是:

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;
    }
});
Object.defineProperty(NodeList.prototype,“addEventListener”{
值:函数(事件、回调、useCapture){
useCapture=(!!useCapture)|错误;
对于(变量i=0;i
我能想到的最好办法是:

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

请注意,这使用ES6功能,因此请确保首先传输它

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

NodeList.prototype.addEventListener = function (event_name, callback, useCapture)
{
    for (var i = 0; i < this.length; i++)
    {
      this[i].addEventListener(event_name, callback, useCapture);
    }
};
同样,您可以执行
forEach
循环

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

编辑:请注意,自2016年11月以来,FF中就存在NodeList.prototype.forEach。不支持IE尽管在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))

你也可以使用原型

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

另一种解决方案是使用事件委派。您只需将eventlistener添加到“.coins”的Closes父级,并在回调中使用event.target来检查单击是否确实是在类为“coins”的元素上进行的。

虽然我知道jQuery并不是所有问题的答案,但它确实使这类问题变得毫无意义:
$('.coins')。on('dragstart',handledragstarg')这不使用循环控制结构和奇数变量。即使你认为它仍然是一个循环,这也很糟糕。谢谢。在我的用例中,相对于传统的for循环,这个方法只保存了5次击键。然而,我喜欢不必定义任何迭代变量……而且,嘿,节省5次击键仍然是一件很重要的事情。也许它可以节省您几次击键,但下一个开发人员需要额外几分钟才能理解。净损失。FYI,即2018年,以及
nodeList.foreach(el=>el.addEventListener('click',callback))
应该适合大多数人。如果没有,ES6允许我们轻松地将类似数组的对象“扩散”到实际数组中。所以类似这样的东西:
[…nodeList].foreach
也应该工作。小心,
getElementsByClassName
返回一个活动节点列表。@SalmanPK-这在这里不重要。
getElementsByClassName()
的结果会立即被使用,不会被存储,因此在使用过程中不会有任何更改的机会。我对这个答案投了赞成票,因为(1)它回答了这个问题,(2)它与其他答案不同,(3)它很聪明,(4)它可能是有人在寻找的答案。然而,我不得不说,任何修改核心Javascript对象原型的事情都会让我感到紧张。@Andrewillems,谢谢!我理解修改本机原型的一般关注点,但我认为这类似于从您不拥有的库扩展类。:)arrow函数的末尾需要一个右括号才能工作。干杯。美味…:-)超级干净——两年过去了,更多的浏览器ES6支持减少了传输的需要。谢谢@okay56k,我更新了答案以反映这一点。
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);
    });
});
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))
NodeList.prototype.addEventListener = function (type, callback) {
    this.forEach(function (node) {
        node.addEventListener(type, callback);
    });
};