jQuery: diferencias entre on() y one()
Cuando trabajamos con jQuery, una de las tareas más habituales es asociar eventos a los elementos de una página: hacer clic, escribir en un campo, enviar un formulario, pasar el ratón por encima, etc.
Para ello podemos utilizar diferentes métodos. Dos de ellos pueden parecer prácticamente iguales a simple vista:
on() one()
Pero hay una diferencia fundamental entre ambos que puede provocar comportamientos inesperados si utilizamos uno cuando realmente necesitábamos el otro.
¿Qué hace el método on() de jQuery?
El método on() permite asociar uno o varios controladores de eventos a los elementos seleccionados.
Por ejemplo:
$("p").on("click", function() {
console.log("Has hecho click en el párrafo.");
});
En este caso estamos indicando a jQuery que, cuando se produzca un evento click sobre cualquiera de los elementos <p> seleccionados, ejecute la función.
Por tanto, si nuestra página contiene varios párrafos:
<p>Primer párrafo</p> <p>Segundo párrafo</p> <p>Tercer párrafo</p>
El evento estará asociado a cada uno de ellos y podremos hacer clic tantas veces como queramos.
Cada clic volverá a ejecutar nuestro código.
Entonces, ¿qué hace one()?
Aquí es donde empieza la confusión.
one() también permite asociar un controlador de eventos, pero con una diferencia importante:
El evento solamente se ejecutará una vez por elemento.
Por ejemplo:
$(".my-class").one("keyup", function() {
var query = $(this).val();
console.log(query);
});
El evento keyup se ejecutará la primera vez que se produzca sobre el elemento y, después, el controlador dejará de ejecutarse para ese elemento.
Es decir, si tenemos un campo de búsqueda:
<input type="text" class="my-class">
y utilizamos:
$(".my-class").one("keyup", function() {
console.log("Se ha pulsado una tecla.");
});
Al escribir la primera tecla veremos el mensaje en la consola.
Al escribir la segunda, tercera, cuarta, quinta… ya no se ejecutará el controlador.
on() frente a one()
La diferencia fundamental puede resumirse de una forma muy sencilla:
| Método | Comportamiento |
|---|---|
on() |
El evento puede ejecutarse todas las veces que se produzca. |
one() |
El evento se ejecuta una sola vez por elemento. |
Por ejemplo:
$(".boton").on("click", function() {
console.log("Click");
});
Podremos hacer clic indefinidamente:
Click Click Click Click Click
Mientras que con:
$(".boton").one("click", function() {
console.log("Click");
});
obtendremos:
Click
Y después, nada más.
Un ejemplo donde one() puede jugarnos una mala pasada
Imaginemos que estamos desarrollando un buscador y queremos ejecutar una función cada vez que el usuario escriba algo.
Podríamos tener algo como:
$(".buscador").on("keyup", function() {
var query = $(this).val();
console.log("Buscando:", query);
});
Esto tiene sentido porque queremos reaccionar a cada pulsación de teclado.
Si el usuario escribe:
wordpress
el evento se ejecutará varias veces mientras escribe.
Pero si por error utilizamos:
$(".buscador").one("keyup", function() {
var query = $(this).val();
console.log("Buscando:", query);
});
nuestro buscador solamente reaccionará a la primera pulsación.
El usuario seguirá escribiendo, pero nuestro controlador ya no volverá a ejecutarse.
Y aquí es donde un simple cambio de una letra puede hacer que nos tiremos un buen rato buscando qué cojones está pasando.
¿Cuándo tiene sentido utilizar one()?
one() no es un método inútil ni mucho menos. Simplemente está pensado para situaciones diferentes.
Puede resultar útil cuando necesitamos que una determinada acción solamente ocurra una vez.
Por ejemplo, podríamos utilizarlo para mostrar un mensaje la primera vez que el usuario interactúe con un elemento:
$(".aviso").one("click", function() {
alert("Has visto este aviso por primera vez.");
});
Otro ejemplo podría ser una inicialización que solamente queremos realizar cuando el usuario interactúe por primera vez con un componente.
En esos casos, one() puede ser precisamente lo que necesitamos.
Delegación de eventos con on()
Hay otra característica de on() especialmente interesante y que merece la pena conocer: la delegación de eventos.
Podemos indicar el elemento que recibe el evento y, además, especificar qué elementos secundarios queremos controlar.
Por ejemplo:
$("#lista").on("click", ".eliminar", function() {
console.log("Se ha pulsado eliminar.");
});
Supongamos que tenemos:
<div id="lista">
<button class="eliminar">Eliminar</button>
<button class="eliminar">Eliminar</button>
<button class="eliminar">Eliminar</button>
</div>
En lugar de asociar individualmente el evento a cada botón, delegamos el evento en #lista y le indicamos que nos interesan los elementos .eliminar.
Esto resulta especialmente útil cuando los elementos se crean dinámicamente mediante JavaScript o AJAX.
Un ejemplo práctico con elementos dinámicos
Imaginemos que inicialmente tenemos:
<div id="usuarios">
<button class="eliminar" data-id="1">Eliminar</button>
<button class="eliminar" data-id="2">Eliminar</button>
</div>
Y posteriormente añadimos otro botón mediante JavaScript:
$("#usuarios").append(
'<button class="eliminar" data-id="3">Eliminar</button>'
);
Con un evento delegado:
$("#usuarios").on("click", ".eliminar", function() {
var id = $(this).data("id");
console.log("Eliminar usuario:", id);
});
el nuevo botón también quedará cubierto por el controlador.
Esta técnica es especialmente útil en interfaces que generan contenido dinámicamente.
Una forma rápida de recordar la diferencia
Si estamos dudando entre ambos métodos, podemos pensar simplemente en la frecuencia con la que queremos ejecutar nuestro código:
// Cada vez que ocurra el evento
$(".boton").on("click", function() {
// Se ejecutará cada vez
});
// Solamente la primera vez
$(".boton").one("click", function() {
// Se ejecutará una vez
});
La diferencia está precisamente ahí.
¿Qué ocurre si utilizamos one() por error?
Este es probablemente el caso más interesante del artículo.
Imaginemos que estamos trabajando en un formulario, un buscador, una tabla dinámica o cualquier componente que dependa de eventos repetidos.
Todo parece funcionar correctamente…
Hasta que hacemos la primera interacción.
Después de ella, el componente parece haberse quedado muerto.
Podemos empezar a buscar problemas en el AJAX, en PHP, en la base de datos, en el navegador, en los selectores, en los plugins…
Y resulta que el problema estaba aquí:
$(".elemento").one("click", function() {
// ...
});
cuando realmente queríamos:
$(".elemento").on("click", function() {
// ...
});
Una sola letra puede cambiar completamente el comportamiento de nuestro código.
Conclusión
Tanto on() como one() sirven para trabajar con eventos en jQuery, pero tienen comportamientos diferentes.
on(): ejecuta el controlador cada vez que se produce el evento.one(): ejecuta el controlador una única vez por elemento.- Delegación con
on(): permite gestionar eventos de elementos actuales y también de elementos que se incorporen dinámicamente al DOM.
Por tanto, si estamos creando un buscador, un formulario interactivo, una tabla AJAX o cualquier componente que necesite reaccionar repetidamente a las acciones del usuario, probablemente queramos utilizar on().
Si, por el contrario, necesitamos ejecutar una acción únicamente una vez, entonces one() puede ser exactamente lo que buscamos.
Y sí: cuidado con esa letra. Porque pasar de on() a one() puede convertir un script perfectamente funcional en uno que parece haberse roto por arte de magia. 😄
Visitas: 94
Automation & Data Specialist | Web Development | Data Processing & Integration
