Estoy usando este código para desvanecer el sitio web cada vez que hay una redirección, y parece funcionar bastante bien la mayor parte del tiempo.
var body = document.body; addEventListener('beforeunload', event => { function redirect() { location.href = event.target.href; body.removeEventListener('transitionend', redirect); } body.addEventListener('transitionend', redirect); body.style.opacity = 0; event.preventDefault(); });(Tengo una transición CSS para la opacidad aquí)
Sin embargo, de vez en cuando, tal vez una vez cada cinco veces, me redirigen a https://example.com/undefined (por ejemplo, mi sitio web) en lugar de a la ubicación correcta. Esto sucede con las URL relativas y absolutas. ¿Por qué sucede esto y por qué solo sucede a veces? Y, ¿cómo puedo solucionarlo?
Por si acaso, mencionaré que estoy usando un servidor Express.js aquí, pero el problema no parece ser del lado del servidor.
ACTUALIZAR:
Aparentemente, si elimino la función de redirección por completo, todavía funciona (y soluciona el problema). Mi teoría actual es que, dado que todavía redirige incluso con preventDefault() (como mencionó @stephancasas), la transición solo ocurre porque la página tarda unas pocas fracciones de segundo en cargarse. Mi código editado se ve así:
addEventListener('beforeunload', event => { body.style.opacity = 0; });Sin embargo, todavía no entiendo completamente lo que está pasando, cualquier explicación sería útil.
Esto probablemente no funcionará o funcionará de manera muy inconsistente. No puede interceptar el evento beforeunload para hacer mucho más que confirmar que el usuario desea abandonar la página (por ejemplo, ingresó datos del formulario y los perdería en una recarga/redireccionamiento).
Según el estándar , la devolución de llamada del detector de eventos debe devolver una cadena que se mostrará en el cuadro de diálogo con el que se le solicitará al usuario.
Esto se hace con un gran propósito, ya que permitir la intercepción de forma libre de este evento podría usarse indebidamente para atrapar los navegadores de los usuarios en ubicaciones específicas.
Dado que su código usa event.target.href, asumí que desea establecer body.style.opacity = 0, cuando un usuario hace clic en un enlace en la página.
Preferiría adjuntar un detector de eventos en todas las etiquetas 'a' (aunque es costoso), ya que le dará un mejor control sobre 'antes de descargar', es fácil de depurar y siempre se redirigirá con el href correcto.
document.addEventListener('DOMContentLoaded', function() { // Make sure DOM is loaded // init global vars var url = ''; var body = document.body; function redirect() { window.location.href = url; // comment this if you want to debug css change effects before redirecting body.removeEventListener('transitionend', redirect); } // Add event listner to transitionend // Use webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd or transitionend based on browser body.addEventListener('transitionend', redirect); // Add event listner to all anchor tags on the page var aTags = document.querySelectorAll('a'); aTags.forEach(function(a) { a.addEventListener('click', e => { var href = e.target.href; if(!href || href == window.location.href) { // return, if the target is same url // add more validations as per your requirements return; } e.preventDefault(); url = href; // update golbal url var body.style.opacity = 0; body.style.transition = 'all 0.5s ease'; // this is important for transitionend listner to trigger }); }); }, false);