Métodos esenciales de Javascript; querySelector y querySelectorAll

En Javascript hay un par de métodos que son fundamentales desde el auge de la manipulación moderna del DOM hace ahora unos 15 años.

Fueron introducidos como parte de la especificación Selectors API de la W3C para permitir la búsqueda de elementos DOM utilizando selectores CSS.

El método querySelector() devuelve el primer elemento que coincide con un selector CSS, ya sea un elemento cualquiera del DOM, un elemento con una clase o un elemento con un id.

Por otro lado el método querySelectorAll() devuelve todos los elementos que coinciden con un selector CSS, en este caso valdrían elementos del DOM y selectores con una clase específica.

A continuación mostramos algunos ejemplos prácticos para verlo más claro.

querySelector()

Como decíamos anteriormente este método devuelve el primer elemento que coincide con un selector CSS. Este selector puede ser cualquier elemento como <p> , <div> , <ul> , <li> , <strong> , <figure> , <section> o cualquier otro elemento válido.

<div> Primer elemento DIV </div>
<div class="clase-del-div"> Segundo elemento DIV </div>
<p> Primer elemento P </p>
<p id="elemento-unico"> Segundo elemento P (único) </p>

Si tenemos el anterior código HTML, usando la propiedad innerText , que devuelve el texto de un elemento HTML, podemos coger el texto del primer elemento div de esta manera:

document.querySelector('div').innerText;
Primer elemento DIV
O el texto del primer elemento p de esta otra manera:

document.querySelector('p').innerText;
Primer elemento P
Podemos buscar por el atributo class (clase) del elemento, así:

document.querySelector('.clase-del-div').innerText;
Segundo elemento DIV
O buscar por el atributo id (identificador único) del elemento, de la misma manera:

document.querySelector('#elemento-unico').innerText;
Segundo elemento P (único)
Para llamar a clases se usa el punto . y para los identificadores únicos se usa la almohadilla # , de la misma manera que hacemos en CSS para definir las sentencias.

Se puede coger cualquier dato del elemento seleccionado, como cualquiera de sus atributos. Imaginemos que tenemos un elemento a con los siguientes atributos:

<a href="https://google.com/" id="miLink" class="text-bold" rel="nofollow">Google</a>

Se puede coger el valor de cualquiera de sus atributos así:

document.querySelector('#miLink').getAttribute('class'); //devuelve: text-bold
document.querySelector('#miLink').getAttribute('href'); //devuelve: https://google.com/
document.querySelector('#miLink').getAttribute('rel'); //devuelve: nofollow

Tarjeta de visita

Vamos a ver un ejemplo más práctico donde pintaremos diferentes datos personales en una especie de tarjeta de visita. Tenemos el siguiente elemento con datos, repartidos en atributos data del propio elemento, vamos a ver como hacerlo.

Tenemos este HTML:

<div 
  id="datos" 
  data-nombre="Josetxu López" 
  data-puesto="Desarrollador Web" 
  data-lenguajes="CSS HTML PHP JAVASCRIPT">
  <div id="tarjeta"><strong>Tarjeta de visita</strong></div>
  <div id="nombre"></div>
  <div id="puesto"></div>
  <div id="lenguajes"></div>
</div>

Con la propiedad dataset podemos coger los valores de todos los atributos data del elemento seleccionado:

//preparamos la variable con los datos del dataset
var nodoDatos = document.querySelector('#datos');

//recogemos los valores del dataset
nodoDatos.dataset;

//esto nos devolvería el siguiente DOMStringMap:
{
nombre: 'Josetxu López',
puesto: 'Desarrollador Web',
lenguajes: 'CSS HTML PHP JAVASCRIPT'
}

Así pues podemos acceder a cada uno de los datos por separado de la siguiente manera:

nodoDatos.dataset.nombre //devuelve: Josetxu López
nodoDatos.dataset.puesto //devuelve: Desarrollador Web
nodoDatos.dataset.lenguajes //devuelve: CSS HTML PHP JAVASCRIPT

Y podemos rellenar la Tarjeta de visita con los datos del dataset usando el método querySelector , así:

//insertamos los datos en los diferentes elementos de la tarjeta
document.querySelector('#nombre').innerText = nodoDatos.dataset.nombre;
document.querySelector('#puesto').innerText = nodoDatos.dataset.puesto;
document.querySelector('#lenguajes').innerText = nodoDatos.dataset.lenguajes;
Tarjeta de visita
Josetxu Lópex
Desarrollador Web
CSS HTML PHP JAVASCRIPT

Para finalizar los ejemplos de querySelector() vamos a crear un botón con el que puedes añadir los datos a la tarjeta tú mismo a través de una función que realizará todos los pasos:

Primero unos estilos CSS muy básicos para la tarjeta de visita:

#datos {
 border: 2px solid #959595;
 background: #323232;
 color: #ffffff;
 border-radius: 10px;
 padding: 10px 15px;
 display: flex;
 flex-direction: column;
 width: fit-content;
}
#tarjeta {
 color: #898989;
 border-bottom: 2px dotted;
 margin-bottom: 10px;
}

Creamos la función Javascript que insertará los datos:

function getDataAndFillCard() {
  //preparamos la variable con los datos del dataset
  var nodoDatos = document.querySelector('#datos');
  //insertamos los datos en los diferentes elementos de la tarjeta
  document.querySelector('#nombre').innerText = nodoDatos.dataset.nombre;
  document.querySelector('#puesto').innerText = nodoDatos.dataset.puesto;
  document.querySelector('#lenguajes').innerText = nodoDatos.dataset.lenguajes;
}

Creamos un botón en HTML que ejecutará la función:

<input type="button" onclick="getDataAndFillCard()" value="Rellenar tarjeta">
Tarjeta de visita

Fácil ¿no?. Ahora vamos a ver el otro método del que hablábamos en el enunciado de este artículo…

querySelectorAll()

Este otro método de Javascript devuelve todos los elementos que coinciden con un selector CSS, ya sean elementos del DOM o selectores con una clase específica. En este caso no nos valen selectores con identificadores únicos ya que no puede haber más de un elemento con el mismo atributo id, y para ese elemento usaríamos el método querySelector() descrito anteriormente.

Veamos unos ejemplos:

<ul>
  <li>Elemento de lista 1</li>
  <li>Elemento de lista 2</li>
  <li>Elemento de lista 3</li>
  <li>Elemento de lista 4</li>
  <li>Elemento de lista 5</li>
</ul>

Para el anterior código HTML podemos coger todos los elemento <li> de la siguiente manera:

document.querySelectorAll('li');

Esto nos devuelve una lista de nodos con cinco elementos, donde el indice 0 será el primer <li>, el índice 1 será el segundo <li> y así sucesivamente…

Guardando esa lista de nodos en una variable podemos acceder a dichos nodos:

//guardamos la lista de nodos en una variable
var nodosLi = document.querySelectorAll('li');

//seleccionamos uno por uno todos los nodos
console.log( nodosLi[0].innerText );
console.log( nodosLi[1].innerText );
console.log( nodosLi[2].innerText );
console.log( nodosLi[3].innerText );
console.log( nodosLi[4].innerText );

//Esto nos devolvería en la consola lo siguiente:
Elemento de lista 1
Elemento de lista 2
Elemento de lista 3
Elemento de lista 4
Elemento de lista 5

De una manera más efectiva podemos usar el método forEach para iterar por los elementos de la variable, mostrando su índice y su contenido. En la función añadimos dos argumentos para cada elemento; el índice index , y el elemento item :

//guardamos la lista de nodos en una variable
var nodosLi = document.querySelectorAll('li');

//iteramos por cada elemento con un forEach
nodosLi.forEach(function(index, item){
   console.log( index + ' - ' + item.innerText ); 
})

//Esto nos devolvería en la consola lo siguiente:
0 – Elemento de lista 1
1 – Elemento de lista 2
2 – Elemento de lista 3
3 – Elemento de lista 4
4 – Elemento de lista 5

Veamos otro ejemplo con elementos <div> con diferentes clases CSS:

<div class="activa">Elemento DIV 1</div>
<div class="oculta">Elemento DIV 2</div>
<div class="activa">Elemento DIV 3</div>
<div class="oculta">Elemento DIV 4</div>
<div class="activa">Elemento DIV 5</div>

Aquí podemos coger solo los elementos <div> con la clase .activa

//guardamos la lista de nodos en una variable
var nodosActiva = document.querySelectorAll('div.activa');

//iteramos por cada elemento con un forEach
nodosActiva .forEach(function(index, item){
   console.log( index + ' - ' + item.innerText ); 
})

// Esto nos devolvería en la consola lo siguiente:
0 – Elemento DIV 1
1 – Elemento DIV 3
2 – Elemento DIV 5

Por otro lado podemos coger solo los elementos con la clase .oculta , y como se ve a continuación no hace falta incluir el elemento div en el método querySelectorAll() :

//guardamos la lista de nodos en una variable
var nodosOculta = document.querySelectorAll('.oculta');

//iteramos por cada elemento con un forEach
nodosOculta .forEach(function(index, item){
   console.log( index + ' - ' + item.innerText ); 
})

//Esto nos devolvería en la consola lo siguiente:
0 – Elemento DIV 2
1 – Elemento DIV 4

Y lógicamente , al no ser necesario incluir el tipo de elemento, se pueden coger diferentes tipos de elementos que tengan la misma clase, como en el siguiente ejemplo, donde vamos a seleccionar todos los elementos con la clase .mezcla , independientemente de que sean div , p o section :

<div class="mezcla">Elemento DIV 1</div>
<div class="normal">Elemento DIV 2</div>
<p class="mezcla">Elemento P 3</p>
<div class="normal">Elemento DIV 4</div>
<section class="mezcla">Elemento SECTION 5</section>
//guardamos la lista de nodos en una variable
var nodosMezclados = document.querySelectorAll('.mezcla');

//iteramos por cada elemento con un forEach
nodosMezclados.forEach(function(index, item){
   console.log( index + ' - ' + item.innerText ); 
})

//Esto nos devolvería en la consola lo siguiente:
0 – Elemento DIV 1
1 – Elemento P 3
2 – Elemento SECTION 5

Esto es solo una pequeñísima muestra de lo que se puede hacer con estos métodos de Javascript. Hay múltiples métodos que podemos combinar para, una vez seleccionado el elemento, hacer mil cosas con él.

Para ver los métodos más usados puedes echar un vistazo a W3Schools donde encontrarás varias listas, desde métodos de strings, hasta métodos de objetos , pasando por métodos de arrays , números , mapas