javascript

Prevenir comportamiento o pedir confirmación para navegar a link en JavaScript

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.

Prevenir comportamiento de un anchor o link con JavaScript

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.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

2 semanas hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.