Hoy veremos cómo prevenir que una etiqueta <a>
siga su comportamiento, o mejor dicho, dependiendo de una condición vamos a prevenir la acción o dejar que ocurra. En otras palabras, veremos cómo evitar la acción de un un anchor con o sin condiciones.
Un poco de historia
(si quieres, puedes saltar al siguiente título, no te perderás nada técnico)
Recientemente estuve haciendo un proyecto escolar pero por las prisas no pude poner una confirmación al eliminar algo. Dicho proyecto está hecho con CodeIgniter (no fue mi elección, lo juro) así que para eliminar se basaba en direcciones URL que llamaban a un controlador. Algo como:
localhost/ejemplo/eliminar/1
Ahora, como es una URL, con el simple hecho de visitarla se elimina (no hay problema, es un proyecto escolar) pero todavía quedaba la duda de cómo pedir una confirmación al usuario, al final me decidí por poner un confirm en el <a>.
Prevenir que se siga el link de un anchor
Esto es muy fácil, si vienes para ver cómo prevenir, la respuesta es:
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#link").addEventListener("click", evento => evento.preventDefault());
});
El DOMContentLoaded
es opcional; así como la obtención del elemento. Lo que importa es agregarle un listener de click, recibir como argumento el evento y llamar a evento.preventDefault()
, de esta manera aunque el usuario haga click, no se irá al enlace especificado.
Igualmente podrías usar querySelectorAll
, hacer un forEach
y en cada uno de ellos agregarle un listener, cosa que veremos más abajo como bonus.
Pedir confirmación para seguir el link o no
Ahora veamos justamente lo que apliqué, y es un confirm que te muestra un mensaje y da dos botones, uno para decir que sí y otro para decir que no. Internamente la función regresa un booleano dependiendo de la opción que el usuario elija.
Nuestro código podría quedar escrito de esta manera:
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#link").addEventListener("click", evento => {
// Prevenir sólo si el usuario dice que no
if (!confirm("¿Realmente quieres ir a mi sitio web?")) {
evento.preventDefault()
}
});
});
Ahora es un poco más largo. Si el usuario no confirma (esto es, que confirm
devuelva false
) entonces prevenimos la acción por defecto. En caso de que se elija que sí, no se hace nada y el click se realiza normalmente.
Bonus: con múltiples elementos
Ahora sí veamos lo que decía hace un momento sobre múltiples elementos y esas cosas. Pues bien, en mi caso el código queda así:
const confirmarEliminacion = evento => confirm("¿Está seguro? esta acción no se puede deshacer") || evento.preventDefault();
document.addEventListener("DOMContentLoaded", function() {
/*
* Esperar a que se cargue el dom, buscar los <a> que tienen un icono de eliminar
* y agregar un callback. Es importante acceder a parentElement.parentElement porque si no,
* estaríamos agregando el listener al <i> en lugar del <a>
* */
document
.querySelectorAll("a > span > i.fa.fa-trash")
.forEach(elemento => elemento.parentElement.parentElement.addEventListener("click", confirmarEliminacion));
});
Como todos mis “botones” (que en realidad son anchors) tienen el icono del bote de basura, puedo seleccionarlos con querySelectorAll
y un selector CSS. Debido a que están dentro de un span
y éste a su vez en un a
, tengo que acceder al abuelo (bueno, al padre del padre).
Una vez que obtenemos al abuelo, le agregamos un listener en el evento click
. Dicho listener será una función que definimos arriba, la cual utiliza una forma corta del if.
Al final, cada que el usuario haga click en un botón para eliminar, se le preguntará. En caso de que elija que no, se previene el evento.
Siento haberlo censurado tanto, pero es por cuestiones de privacidad y cosas de esas.
Conclusiones y lecturas recomendadas
Lo sé, lo sé, es un poco sucio pero nos sacará de un apuro. Además, sólo fue un hack que solucionaré pronto. Cabe mencionar que el problema principal es que lo hice mayormente con PHP, y luego le puse encima la funcionalidad de JavaScript.
Mira aquí lo que es const en JavaScript, y aquí lo que son las funciones flecha en JavaScript.