Conozcamos con detalle el método each del core de jQuery, para ejecutar una función en cada uno de los elementos de un grupo.
Siempre que desearrollamos en Javascript necesitamos crear el mínimo código posible, en la medida de lo posible, para que los scripts de la página tarden menos en descargar. Además el código debe de ser expresivo. Gracias a librerías como jQuery esto es más sencillo y métodos como each()
son una buena muestra de ello.
El método each()
pertenece al juego de funciones del CORE de jQuery, cuyas particularidades ya comenzamos a analizar en el manual de jQuery. Se trata de un método para realizar acciones con todos los elementos que se encuentran en una selección realizada con la función jQuery -también llamada función $()-.
Además de compacto, each()
es útil porque nos da una manera cómoda de iterar con elementos de la página y hacer cosas con ellos, más o menos complejas, de una manera rápida y sin utilizar mucho código para definir el bucle.
Cómo funciona each
Each es un método que se utiliza sobre un conjunto de elementos que hayamos seleccionado con la función jQuery. Con each()
realizamos una iteración por todos los elementos del DOM que se hayan seleccionado.
El método each()
recibe una función que es la que se tiene que ejecutar para cada elemento y dentro de esa función con la variable "this
" tenemos una referencia a ese elemento del DOM. Adicionalmente, la función que se envía a each()
, puede recibir un parámetro que es el índice actual sobre el que se está iterando.
Quiero explicar las bondades de each()
de manera práctica. Por ejemplo, veamos esta línea de código:
$("p").css("background-color", "#eee");
Como ya sabemos, con $("p")
seleccionamos todos los párrafos de la página. Luego con el método CSS asignamos un estilo, en este caso para cambiar el color del fondo. Esto en realidad jQuery lo hace con una iteración con todos los párrafos de la página, sin que tengamos que hacer nosotros nada más y es genial que se permita en el uso de la librería. ¿Pero qué pasa si queremos cambiar el fondo de los párrafos utilizando colores alternos?
En este caso no podemos hacerlo en una sola línea de código, pero each
nos vendrá como anillo al dedo.
Imaginemos que tenemos una serie de párrafos en la página y queremos cambiar el color de fondo a los mismos, de manera que tengan colores alternos, para hacer dinámicamente un típico diseño para los listados.
Obviamente, esto de poner colores alternos se podría hacer más sencillo con un par de reglas de CSS. Quizás no sea el mejor ejemplo en ese sentido, pero imagina que el color dependiese del contenido del párrafo. Ese ejemplo lo veremos un poco más adelante.
Entonces podríamos hacer lo siguiente:
$("p").each(function(i) {
if(i % 2 == 0){
$(this).css("background-color", "#eee");
} else {
$(this).css("background-color", "#ccc");
}
});
Con $("p")
tengo todos los párrafos. Ahora con each
puedo recorrerlos uno a uno. Para cada uno ejecutaremos la función que enviamos como parámetro a each()
. En esa función recibo como parámetro una variable "i" que contiene el índice actual sobre el que estoy iterando.
Con if(i%2==0)
estoy viendo si el entero del índice "i
" es par o impar. Siendo par coloco un color de fondo al elemento y siendo impar coloco otro color de fondo.
Como se puede ver, con la variable "this
" tenemos acceso al elemento actual. Pero OJO, que este elemento no es un objeto jQuery, así que no podríamos enviarle métodos del framework jQuery hasta que no lo expandamos con la función jQuery. Así pues, tenemos que hacer $(this)
para poder invocar al método css()
. Por si no queda claro este punto mirar las diferencias entre estas dos líneas de código:
Por un lado tenemos esta línea en la que no estamos extendiendo this
y por tanto no funcionaría.
this.css("background-color", "#ccc"); // Esto no funcionaría porque this no tiene el métoo css()
Por otro lado tenemos este otro código.
$(this).css("background-color", "#ccc"); // Esto sí funcionaría
-
En la primera línea no estaríamos extendiendo la variable
this
con las funcionalidades de jQuery, luego no funcionaría. - En la segunda línea, que es la que habíamos utilizado en el script de ejemplo, sí estamos extendiendo la variable "
this
" con la función jQuery. De ese modo, se puede invocar a cualquier método de jQuery sobre los elementos.
Este sería el código de una página web que hace uso de este ejemplo:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplo de uso del método each()</title>
</head>
<body>
<h1>Ejemplo de uso del método each()</h1>
<p>Primer párrafo</p>
<p>Otro párrafo para recorrer con each()</p>
<p>Tecer párrafo</p>
<p>Uno más</p>
<p>y acabo...</p>
<script src="../../js/jquery-3.6.3.js"></script>
<script>
$(document).ready(function () {
$("p").each(function (i) {
if (i % 2 == 0) {
$(this).css("background-color", "#eee");
} else {
$(this).css("background-color", "#ccc");
}
});
});
</script>
</body>
</html>
Retornando valores en la función que enviamos a each
Ahora vamos a ver un par de posibilidades interesantes al utilizar each()
. Resulta que la función que enviamos como parámetro a each()
puede devolver valores y dependiendo de éstos, conseguir comportamientos parecidos a los conocidos break o continue de los bucles Javascript.
Si la función devuelve "false
", se consigue detener por completo el proceso de iteraciones de each()
. Esto es como si hiciéramos el típico "break
".
Si la función devuelve "true
", se consigue pasar directamente a la próxima iteración del bucle. Es como hacer el típico "continue
".
Para ver estos dos casos realizaremos otro ejemplo de uso de each()
.
Tenemos varios DIV, donde cada uno tiene un texto.
<div>red</div>
<div>blue</div>
<div>red</div>
<div>white</div>
<div>red</div>
<div>green</div>
<div>orange</div>
<div>red</div>
<div>nada</div>
<div>red</div>
<div>blue</div>
Ahora queremos hacer un recorrido a esos DIV y en cada uno, mirar el texto que aparece. Entonces colocaremos como color del texto del DIV el color que aprece escrito en el DIV. Pero con dos casos especiales:
- Si el texto del DIV es "white", entonces no queremos hacer nada con ese elemento.
- Si el texto del DIV es "nada", entonces detendremos el bucle y dejaremos de colorear los siguientes elementos.
Esto lo podríamos hacer con el siguiente código:
$("div").each(function (i) {
elemento = $(this);
if (elemento.html() == "white")
return true;
if (elemento.html() == "nada")
return false;
elemento.css("color", elemento.html());
});
Para acabar podemos ver el código HTML completo de una página que realiza este comportamiento especial.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Recorrido a divisiones para poner colores</title>
<style>
div {
font-size: 1.5rem;
}
</style>
</head>
<body>
<div>red</div>
<div>blue</div>
<div>red</div>
<div>white</div>
<div>red</div>
<div>green</div>
<div>orange</div>
<div>red</div>
<div>nada</div>
<div>red</div>
<div>blue</div>
<script src="../../js/jquery-3.6.3.js"></script>
<script>
$("div").each(function (i) {
elemento = $(this);
if (elemento.html() == "white")
return true;
if (elemento.html() == "nada")
return false;
elemento.css("color", elemento.html());
});
</script>
</body>
</html>
Ejemplo de recorrido a elementos de un formulario con each()
Vamos a ver otro ejemplo que nos servirá para practicar un poco más con each()
y todo lo que hemos aprendido hasta aquí.
Vamos a suponer que tenemos un formulario en la página y, cuando enviamos el formulario, queremos realizar la validación de los campos que hay dentro. Nuestra validación será muy sencilla: simplemente queremos asegurarnos que se haya escrito algo dentro de cada campo.
Vamos a ver el código HTML de este supuesto formulario que queremos validar:
<form id="elform" action="enviar.php" method="post">
<p>
<label>Uno:</label>
<br>
<input type="text" id="uno">
</p>
<p>
<label>Dos:</label>
<br>
<input type="text" id="dos">
</p>
<p>
<label>Tres:</label>
<br>
<input type="text" id="tres">
</p>
<button>Enviar</button>
</form>
Para validarlo tendría dos opciones:
- Acceder campo a campo a través de sus identificadores, realizando la comprobación sobre si tienen o no algo escrito.
- Conseguir todos los campos input dentro de un objeto jQuery y hacer un bucle con each(), verificando si tienen algo escrito con una simple repetición.
Por supuesto, si lo conseguimos hacer con un bucle será mucho mejor, ya que podríamos tener un número enorme de campos y no queremos repetir nuestro código un montón de veces, siendo que la validación siempre será la misma.
Entonces podríamos usar un script, basado en jQuery y el método each(), como el que ves a continuación.
$('#elform').submit(function(e) {
$('input', '#elform').each(function() {
if(this.value == '') {
alert('Todos los campos input deben tener un valor');
e.preventDefault();
return false;
}
});
});
Aquí estamos usando varias cosas sobre eventos que no hemos tratado todavía. Quizás quieras saber más sobre la definición de eventos en jQuery, o el significado del método preventDefault() sobre el objeto evento.
Para lo que nos interesa en este artículo, el uso de each
, lo que nos importa es ver cómo estamos accediendo a un objeto jQuery que nos incluye todos los campos input que hay dentro del formulario con id "elform
". Esos inputs los estamos seleccionando con esta invocación a la función $, enviando un selector y un contexto.
$('input', '#elform')
Para recorrer todos los input entonces hacemos este tratamiento.
$('input', '#elform').each(function() {
// aquí puedo hacer cosas con cada uno de los input
});
También es muy interesante que observes que, cuando detecto que la propiedad value
de uno de los elementos input tiene una cadena vacía, hacemos uso de preventDefault() para evitar que el formulario se envíe y devolvemos false
, lo que nos permite evitar que se sigan verificando todos los input en adelante (simplemente con que uno esté vacío entonces ya no necesito verificar más).
El ejemplo es un poco más avanzado, pero resulta bastante ilustrativo de lo que estamos aprendiendo. Espero que te haya aclarado un poco más el uso de each
de jQuery.
Conclusión
Hemos aprendido el método de jQuery <code>each</code>, que nos permite hacer recorridos a objetos jQuery donde tenemos una colección de elementos. Este método nos permite iterar de una manera expresiva y compacta, realizando cualquier tipo de procesamiento para cada uno de los elementos que tenemos en un objeto jQuery.
Por supuesto, este método se usa mucho, ya que recorrer elementos es algo muy típico a la hora de desarrollar código de manipulación del DOM. Por tanto, lo usaremos muchas veces a lo largo del manual y podrás ver otros ejemplos interesantes.
De momento lo dejamos por aquí para, en el siguiente artículo abordar una propiedad que nos permite saber el número de elementos que tenemos seleccionados en un objeto jQuery.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...