Cómo iterar sobre elementos DOM desde querySelectorAll

Al trabajar con JavaScript estándar, a menudo se requiere encontrar una lista de elementos en el Modelo de objetos del documento (DOM) e iterar sobre ellos. Por ejemplo, encontrar todas las etiquetas de anclaje con una clase CSS específica y adjuntarles un controlador de eventos de clic.

El método querySelectorAll() es el que se usa comúnmente para seleccionar todos los elementos de un tipo específico. Devuelve una lista de elementos DOM que coinciden con los selectores especificados. La lista devuelta no es una matriz, sino un objeto NodeList que contiene una colección de nodos:

// select all anchor tags
const anchors = document.querySelectorAll('a.open-article');

// TODO: iterate over `NodeList` elements and attach a click handler

Hay muchas formas de recorrer un NodeList objeto en JavaScript. Mirémoslos.

forEach() Método

La forma más sencilla y fácil de recorrer los resultados devueltos por querySelectorAll() es usando el método forEach(). Esta función ejecuta la función dada una vez para cada nodo en el NodeList .

Aquí hay un ejemplo:

anchors.forEach(anchor => {
    anchor.addEventListener('click', () => {
        console.log('Link is clicked!');
    });
});

El forEach() método para NodeList solo funciona en navegadores modernos. Si desea admitir navegadores antiguos como Internet Explorer, use el siguiente pequeño truco en su lugar:

[].forEach.call(anchors, function (anchor) {
    anchor.addEventListener('click', function () {
        console.log('Link is clicked!');
    });
});

También puede usar el operador de propagación para convertir el NodeList a un Array objeto. Esto le dará acceso a todos los métodos de matriz, incluido forEach() :

[...anchors].forEach(anchor => {
    anchor.addEventListener('click', () => {
        console.log('Link is clicked!');
    });
});

for...of Bucle

Otra forma de recorrer un objeto NodeList es usando la instrucción ES6 for...of. Tiene una sintaxis clara y concisa, y es compatible con todos los navegadores modernos:

for (const anchor of anchors) {
    anchor.addEventListener('click', () => {
        console.log('Link is clicked!');
    });
}

Los navegadores modernos también son compatibles con entries() , keys() y values() métodos en un NodeList objeto. Estos métodos devuelven un iterador que le permite recorrer todos los pares clave-valor. Los valores son siempre Node objetos:

// entries() can be replaced with keys() or values()
for (const anchor of anchors.entries()) {
    anchor.addEventListener('click', () => {
        console.log('Link is clicked!');
    });
}

Simple for Bucle

Si desea admitir la cantidad máxima de navegadores, incluido Internet Explorer (IE), el viejo for loop es el camino a seguir:

for (let i = 0; i < anchors.length; i++) {
    anchors[i].addEventListener('click', () => {
        console.log('Link is clicked!');
    });
}

El ejemplo anterior utiliza la sintaxis de funciones de flecha de ES6. No funcionará en IE y navegadores anteriores similares. Así que tenemos que usar la sintaxis de declaración de la función ES5:

for (var i = 0; i < anchors.length; i++) {
    anchors[i].addEventListener('click', function () {
        console.log('Link is clicked!');
    });
}

Bibliotecas de terceros

Si ya está utilizando jQuery, no es necesario utilizar ninguno de los métodos anteriores:

$('a.open-article').on('click', () => {
    console.log('Link is clicked!');
});

En marcos de JavaScript como Angular, React y Vue, no debe usar jQuery. Más bien, usa el _.forEach de Lodash método:

_.forEach(anchors, (anchor, key) => {
    anchor.addEventListener('click', () => {
        console.log('Link is clicked!');
    });
});