queryselectorall - iterate nodelist javascript
addEventListener en NodeList (7)
¿Es compatible NodeList addEventListener. Si no, ¿cuál es la mejor manera de agregar EventListener a todos los nodos de NodeList? Actualmente estoy usando el fragmento de código como se muestra a continuación, hay una mejor manera de hacerlo.
var ar_coins = document.getElementsByClassName(''coins'');
for(var xx=0;xx < ar_coins.length;xx++)
{
ar_coins.item(xx).addEventListener(''dragstart'',handleDragStart,false);
}
El ejemplo más simple es agregar esta funcionalidad 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);
}
};
Ahora puedes hacer:
document.querySelectorAll(".my-button").addEventListener("click", function ()
{
alert("Hi");
});
De la misma manera, puedes hacer un bucle forEach
NodeList.prototype.forEach = function (callback)
{
for (var i = 0; i < this.length; i++)
{
callback(this[i], i);
}
};
Utilizando:
document.querySelectorAll(".buttons").forEach(function (element, id)
{
input.addEventListener("change", function ()
{
alert("button: " + id);
});
});
EDITAR : tenga en cuenta que NodeList.prototype.forEach existe desde noviembre de 2016 en FF. Aunque no es compatible con IE
Lo mejor que pude encontrar fue esto:
const $coins = document.querySelectorAll(''.coins'')
[...$coins].forEach($coin => $coin.addEventListener(''dragstart'', handleDragStart));
Tenga en cuenta que esto utiliza las funciones de ES6, así que asegúrese de transpilarlo primero.
No hay manera de hacerlo sin recorrer cada elemento. Podría, por supuesto, escribir una función para que lo haga por usted.
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 versión más especializada:
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);
Y, aunque no preguntaste sobre jQuery, este es el tipo de cosas en las que jQuery es particularmente bueno en:
$(''.coins'').on(''dragstart'', handleDragStart);
Realmente hay una manera de hacer esto sin un bucle:
[].forEach.call(nodeList,function(e){e.addEventListener(''click'',callback,false)})
Y esta forma se usa en una de mis bibliotecas de ayuda de una línea: nanoQuery .
Supongo que otra opción sería definir addEventListener
en NodeList
usando Object.defineProperty
. De esa manera puede tratar la Lista de nodos como si fuera un solo Nodo.
Como ejemplo, creé un jsfiddle aquí: http://jsfiddle.net/2LQbe/
El punto clave es este:
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;
}
});
También puedes usar prototipos.
NodeList.prototype.addEventListener = function (type, callback) {
this.forEach(function (node) {
node.addEventListener(type, callback);
});
};
en es6, puede hacer una matriz desde la lista de nodos, usando Array.from, por ejemplo,
ar_coins = document.getElementsByClassName(''coins'');
Array
.from(ar_coins)
.forEach(addEvent)
function addEvent(element) {
element.addEventListener(''click'', callback)
}
o simplemente usa las funciones de flecha
Array
.from(ar_coins)
.forEach(element => element.addEventListener(''click'', callback))