addEventListener su NodeList

NodeList supporta addEventListener. In caso contrario, qual è il modo migliore per aggiungere EventListener a tutti i nodes di NodeList. Attualmente sto usando lo snippet di codice come mostrato qui sotto, c’è un modo migliore per farlo.

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

Non c’è modo di farlo senza passare attraverso ogni elemento. Potresti, naturalmente, scrivere una funzione per farlo per te.

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

o una versione più specializzata:

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

E, anche se non hai chiesto informazioni su jQuery, questo è il tipo di cose a cui jQuery è particolarmente bravo:

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

In realtà esiste un modo per farlo senza un ciclo:

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

E in questo modo viene utilizzato in una delle mie librerie di helper one-liner: nanoQuery .

Il meglio che ho potuto inventare era questo:

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

Nota che questo usa le funzionalità di ES6, quindi assicurati di trascriverlo prima!

in es6, puoi fare un array da nodelist, usando Array.from, es

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

o semplicemente usare le funzioni freccia

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

L’esempio più semplice è aggiungere questa funzionalità a NodeList

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

Ora puoi fare:

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

Allo stesso modo, puoi fare un ciclo forEach

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

usando:

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

EDIT : notare che NodeList.prototype.forEach esiste da novembre 2016 in FF. Nessun supporto IE però

Suppongo che un’altra opzione sarebbe quella di definire addEventListener su NodeList usando Object.defineProperty . In questo modo puoi trattare NodeList come se fosse un singolo nodo.

Ad esempio, ho creato un jsfiddle qui: http://jsfiddle.net/2LQbe/

Il punto chiave è questo:

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