NodeList上的addEventListener

Din*_*.R. 28 javascript nodelist addeventlistener

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);
}
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 33

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

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); 
Run Code Online (Sandbox Code Playgroud)

或更专业的版本:

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); 
Run Code Online (Sandbox Code Playgroud)

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

$('.coins').on('dragstart', handleDragStart);
Run Code Online (Sandbox Code Playgroud)

  • @SalmanPK - 这应该不重要.`getElementsByClassName()`的结果立即使用而不是存储,因此在使用它时没有机会改变它. (3认同)

Kri*_*ekk 15

我能想出的最好的是:

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

请注意,这使用了ES6功能,因此请务必先将其转换!

  • 超级干净 - 两年过去了,通过更多浏览器 ES6 支持减少了转译的需要。 (2认同)

Mul*_*sum 9

实际上一种方法可以在没有循环的情况下执行此操作

[].forEach.call(nodeList,function(e){e.addEventListener('click',callback,false)})
Run Code Online (Sandbox Code Playgroud)

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

  • 也许它会为您节省一些按键,但是下一个开发人员需要额外花费几分钟来理解它.净亏损. (12认同)
  • 即使你认为它仍然是一个循环,这是非常坏的.谢谢. (8认同)
  • 这不使用循环控制结构和奇数变量. (7认同)
  • 仅供参考,现在是 2018 年,[NodeLists 在大多数浏览器中都是可迭代的](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility)。`nodeList.foreach(el =&gt; el.addEventListener('click', callback))` 应该适合大多数人。如果没有,ES6 允许我们轻松地将类似数组的对象“扩展”为实际的数组。所以像这样:`[...nodeList].foreach` 也应该工作。 (2认同)

Pro*_*r08 6

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

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

现在您可以执行以下操作:

document.querySelectorAll(".my-button").addEventListener("click", function ()
{
    alert("Hi");
});
Run Code Online (Sandbox Code Playgroud)

同样,您可以forEach循环

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

使用方法:

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

编辑:请注意,自2016年11月以来,FF中一直存在NodeList.prototype.forEach。虽然没有IE支持


Dar*_*nça 5

在es6中,您可以使用Array.from从nodelist中创建一个数组,例如

ar_coins = document.getElementsByClassName('coins');
Array
 .from(ar_coins)
 .forEach(addEvent)

function addEvent(element) {
  element.addEventListener('click', callback)
}
Run Code Online (Sandbox Code Playgroud)

或只使用箭头功能

Array
  .from(ar_coins)
  .forEach(element => element.addEventListener('click', callback))
Run Code Online (Sandbox Code Playgroud)