JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

TRUCO: Cómo detectar el cierre o la salida de una página Web

Seguramente te has topado en algunas ocasiones con que, tras haber rellenado algunos campos de un formulario , algunas aplicaciones Web te avisan si pretendes cerrar la ventana o abandonar la página, ya que perderías los datos.

Yo por ejemplo utilizo bastante el webmail de Google, GMail, y muchas veces si acabo de enviar un correo y cierro muy rápido la ventana, como el correo aún no ha terminado de enviarse me avisa para evitar que se pierda.

¿Cómo es posible conseguir esto?

La verdad es que es muy sencillo y se consigue en la práctica totalidad de los navegadores modernos (excepto en Opera) gracias al evento onbeforeunload de la ventana del navegador.

Consideremos el siguiente ejemplo:

<html>
<head>
<title>Prueba de abandono de página</title>
<script language="JavaScript" type="text/javascript">
     

    var bPreguntar = true;

     

    window.onbeforeunload = preguntarAntesDeSalir;

     

    function preguntarAntesDeSalir()

    {

      if (bPreguntar)

        return "¿Seguro que quieres salir?";

    }
</script>
</head>
<body>
<h1>Ejemplo de abandono de página</h1>
<p>Por defecto preguntará hasta que pulses el botón de "No preguntar"</p>
<input type="button" value="Preguntar" onclick="bPreguntar = true;" >
&nbsp;&nbsp;
<input type="button" value="No preguntar" onclick="bPreguntar = false;" >
<br/><br/>
<a href="http://www.jasoft.org">Ir a otra página</a>
</body>
</html>

Deja de lado el código JavaScript por un momento.

Como vemos se trata de una página muy sencilla. contiene una cabecera, un texto explicativo, dos botones y un enlace. Su aspecto es el siguiente:

AbandonoPagina_1

Hemos creado una variable booleana, bPreguntar, con el valor por defecto verdadero, de modo que servirá para controlar si debemos preguntarle o no al usuario si de verdad quiere abandonar la página (por defecto se lo preguntaremos).

Lo único que tenemos que hacer es interceptar el evento onbeforeunload de la ventana actual y asignarle un manejador apropiado, en este caso le h llamado preguntarAntesDeSalir.

Dentro de este evento el navegador controlamos si se debe preguntar por el abandono de la página o no. El navegador entiende que si como resultado de este evento pasamos una cadena de texto, deberá preguntarle al usuario con ella si quiere abandonar o no la página, mostrando el texto especificado, y dándole a elegir entre ambas opciones (dejar la página o no):

AbandonoPagina_2

Como vemos apenas podemos controlar el aspecto del diálogo, limitándose a mostrar el texto junto con otro texto estándar del propio navegador.

La única "pega" es precisamente que no seremos capaces de controlar el aspecto de este diálogo y que éste cambia además entre los diferentes navegadores (los tengo todos instalados en inglés):

AbandonoPagina_3

Como vemos Firefox hace caso omiso del texto que le hemos indicado y muestra un mensaje propio. Chrome/Safari e Internet Explorer muestran un mensaje estándar pero lo acompañan de nuestro texto para poder dar una información más detallada. Personalmente el diálogo que me parece más claro es el de Internet Explorer.

Este evento se definió por primera vez en Internet Explorer 4 (¡en 1997!), y los demás navegadores le fueron añadiendo soporte mucho más adelante. En la actualidad está soportado por todas las versiones modernas de los navegadores. Yo lo he probado con Internet Explorer 7, 8 y 9, con Firefox 4, 5, 6 y 7 y con Google Chrome. Debería funcionar perfectamente con Safari tanto en Windows como en Mac. Me consta que no funciona con Opera pero no lo he probado.

¡Espero que te resulte útil!

José Manuel Alarcón José Manuel Alarcón
Fundador de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (51) -

Guatemala Carlos Sincuir

Excelente Jose!!
Funciona muy bien, hasta intentado cerrar el navegador.
Esto me sera de mucha utilidad.

Saludos.

Carlos.

Responder

Muy útil,ya lo implemente en mi website

Responder

Para utilizando este código desde un ventana emergente(pop-up) modifique el codigo para que funcionara de esta manera

function redireccionar() {
                window.opener.location.href = "Default.aspx"
        }

en la etiqueta <body> se debe agregar el evento onbeforeunload="redireccionar()"
para que llame la funcion redireccionar.

lo que hace "window.opener.location.href" es llamar la ventana padre del pop-up
de la cual se abrio el la ventana, espero me allá explicado bien , saludos

Responder

hola Isidro por favor puedes ayudarme con lo que hiciste o modificaste?.

Responder

Esto lo he provado, pero no funciona, solo funciona cuando la pagina esta con ajax totalmente.

Responder

Spain José Manuel Alarcón

Sí que funciona. No sé qué significa eso de que "la página esté con AJAX totalmente"...

Si te fijas bien en los requisitos de navegadores quizá te pueda ayudar, pero los ejemplos están probados con todos ellos. Prueba bien...

Responder

Argentina Gaston Carrizo

Quería agradecerte el consejo, la verdad que desconocía este evento que en verdad me solucionó un problema importante. Agendo esta página por futuras dudas. Si puedo aportar en algo tenés mi email. Saludos. Gaston.

Responder

Spain José Francisco Ibarra

Es posible actuar si el usuario ha elegido una u otra cosa? Esto es, si por ejemplo el usuario responde que si quiere salir, podría avisar al servidor por medio por ejemplo de ajax de que ese usuario va a salir?

Seria algo como esto, pero no funciona, con esto se suplanta, o ponemos una pregunta antes de darle la información al navegador
window.onbeforeunload = function (evt) {
            if (confirm('Are you sure to exit')) {
                'aqui hacer una llamada a server informando
                return true;

            }
            else
                return false;
        }

Responder

Spain José M. Alarcón

Hola,

En este evento sólo se puede devolver un mensaje y no hay forma de saber qué ha elegido el usuario.

Saludos

Responder

GrAcIaS pOr Tu ApOrTe...
De GrAn AyUdA!!!

Responder

Mexico ReN Fractal

Muchas Gracias aqui en el trabajo desde hace mucho me estaban pidiendo que al cerrar con la X me actualizara la base de datos a sesión cerrada :D


Les dejo un ejemplo con Ajax

        <script language="JavaScript" type="text/javascript">
            window.onbeforeunload = function(){
                $.ajax({
                    type: "POST",
                    url: "salida.jsp",
                    dataType:"json",
                    data: {},
                    async : false,
                    success : function(){
                    }
                });
            }
        </script>

Responder

Spain jonathan camargo

Disculpa amigo, puedes ser mas especifico de como va todo con el javascript? es que no me queda claro.... Lo que pasa es que quiero que apenas intenten cerrar en navegador o la pestaña se dispare el ajax enviando datos a la base de datos... Espero me puedas ayudar, muchas gracias de ante mano!

Responder

Peru tito contreras

buen aporte con ese codigo llamas al php, y ya en el php cierras sesion y actualizas cualquier valor de la BD referente al estado de conectado del usuario

Responder

La función onbeforeunload no funciona para Firefox 28 o Firefox 29, y tampoco para la onunload, como podría hacerle para que me funcione en esas versiones

Responder

Spain José Manuel Alarcón

Antonio,

¿de dónde sacas que Firefox no soporta ese evento?
Firefoz soporta este evento (developer.mozilla.org/.../beforeunload) y su correspondiente manejador de evento en JavaScript (developer.mozilla.org/.../window.onbeforeunload) desde la versión 1, y lo sigue soportando en la última versión.

Prueba a copiar y pegar el código de arriba y usarlo en Firefox y verás que te funciona perfectamente.

Saludos.

Responder

hola espero me puedan ayudar, como se haria una funcion para que funcione con una pagina maesta, manejo VS 2010 y que solo me aparesca el mensaje cuando se quiera cerrar la ventana en la X, espero me puedan ayudar, gracias

Responder

Bolivarian Republic of Venezuela Josué Leo.. Moreno

Una pregunta amigo. Quiero hacer que al cerrar la ventana, se cierre la sesión, pero el problema con este evento, es que detecta hasta recargar la pagina. Como hago para que solo detecte el cierre de la ventana. Y no que detecte recargar pagina.

Responder

Buenos dias
disculpa amigo  si lograste hacer eso ?? , ando en la mismas me exigen que se cierre sesión cuando se cierra la pag.  y no e podido ya que cuando oprimen cualquier otro boton lo detecta como si fuesen a cerrar la pag. y no me permite navegar normal en mi pag.
requiero  eso urgente , no se si me ya logro y me pueda ayudar

Responder

yo tambien quiero lo mismo

Responder

Mauricio Parra

Josué, tengo exactamente el mismo problema, por favor si lo solucionaste ayudame.

Responder

Julio Polo

Hola!, estoy en la misma situación que ustedes, alguno logro solucionarlo?

Responder

amigo mil gracias, quería dejarte el agradecimiento, funciona perfectamente.

Responder

Bolivarian Republic of Venezuela Gerardo Francisco Simancas Matos

Buenos dias pero yo quieri que el evento se dispare solo cuando voy a cerrar (x) la ventana del navegador, no cuando pulso un link, o un boton...

Responder

Spain José M. Alarcón

Aprende a leer, por favor. Gracias :-)

Responder

ya lei bien, pero habra una forma de que  funcione para solo cerrar(x), la ventana?

Responder

Spain José Manuel Alarcón

Vamos a ver... El título del post lo pone bien claro: "TRUCO: Cómo detectar el cierre o la salida de una página Web "

Esto funciona SIEMPRE, incluso al cerrar la ventana. No hay que darle a ningún botón.
Los botones del ejemplo los puse para que se vea cómo puedes activar o desactivar por código la características, pero funciona siempre.

Responder

Bolivarian Republic of Venezuela Gerardo Francisco Simancas Matos

lo mismo que pide juan

Responder

Bolivarian Republic of Venezuela Gerardo Francisco Simancas Matos

ahora el que tienes que aprender a leer eers tu! si yo se que funciona, lo que quiero
para ser mas especifico, que se cierre una sesion cuando un usuario esta en una pagina segura pero le da click
a la (x), que so la pagina tiene enlaces, y el quiera a otra pagina segura del mismo sitio no salga ese mensaje, en mi caso no se destruya la sesion, solo cuando el usuario cierre la ventana (x), sin que le haya dado click al enlace " cerrar sesion" o "salir", me explique bien?

Responder

Sergi Ortiz Gómez

Hola. Yo lo que quiero es que al hacer click en cualquier enlace o boton salga un div de "cargando" al entrar en la pagina me funciona perfectamente, pero en las esperas hasta que el servidor responde es donde no consigo se se vea. aqui les dejo mi codigo

    <script>
      function detectarDescargaCarga() {
          document.getElementById("carga").style.display = "block";
          $("#carga").css("display", "block");
          $("#carga").style.display = "block";
          //alert("hice click");
      }

      $(document).ready(function () {          
          window.onload = cerrar;
          function cerrar() {
              $("#carga").animate({ "opacity": "0" }, 1000, function () { $("#carga").css("display", "none"); });
          }
          $("#carga").click(function () { cerrar(); });
          window.onbeforeunload = function exit() { detectarDescargaCarga };
      });
    </script>

<div title="Click para Cerrar" id="carga" style="cursor:pointer;border-radius:10px;display:block;-moz-border-radius:10px;-webkit-border-radius:10px;box-shadow:inset #696763 0px 0px 14px;background-position:center;background-size:100%;background-color:#fff;width:300px;color:#fff;text-align:center;height:170px;padding:52px 12px 12px 12px;position:fixed;top:30%;left:40%;z-index:6;">
<img id="imgLoading" src="../../img/Internet.gif" alt="Loading">
</div>

Responder

Aqui muestro una solucion  a lo que Sergi dijo

    <script>
      function cargando() {
              $("#carga").animate({ "opacity": "1" }, 1000, function () { $("#carga").css("display", "Block"); });        
      }

      function cerrar() {
          $("#carga").animate({ "opacity": "0" }, 1000, function () { $("#carga").css("display", "none"); });
      }

      $(document).ready(function () {          
          window.onload = cerrar;
          $("#carga").click(function () { cerrar(); });
      });

      $(document).click(function () {
          window.onload = cargando;
      });
    </script>

Lo he probado y funciona. Al asignar al evento click del documentos, siempre que se hace click ejecuta ese escrip. Ademas de los que tengan cada uno de los elementos de la pagina en su respectivo click.

Responder

by Jose M. Alarcon

Chicos: si estáis usando jQuery (que es justo lo que trato de evitar con el contenido de mi post) realmente no os hace falta para nada usar el código que propongo. Lo demás no tiene nada que ver con el contenido del post.

En cualquier caso, gracias por comentar. Quizá a alguien le resulte útil.

Saludos.

Responder

Beyker Guerrero

buenas tardes amigos, quisiera saber como hago para que antes de que cierren mi pagina web en un navegador realizar una consulta. Esto para saber que usuarios estan conectados y que usuarios no estan conectados. No se si me di a explicar, por favor responder a la brevedad posible

Responder

by Jose M. Alarcon

Hola:

En el evento unload de la página puedes lanzar una petición al servidor, pero no puedes contar con que te la devuelva y la puedas procesar en el cliente ni tampoco puedes cancelar el cierre de la página. Además tampoco puedes distinguir entre que se cierre una pestaña o ventana o simplemente que se navegue a otra página de tu mismo dominio u otro distinto. Tienes que tenerlo claro.

Ahora bien, a pesar de estas limitaciones, dependiendo de lo que quieras hacer puede ser suficiente usar este evento.

Saludos.

Responder

He probado el ejemplo y me funciona pero no me deja personalizar el mensaje, he probado con tres navegadores, firefox, chome e ie solo muestra el mensaje por defecto del navegador, que puede estar mal?

Saludos

Responder

by Jose M. Alarcon

Hay que leer con atención los posts... :-(

Precisamente eso es lo que dice: que no se puede hacer personalizando el mensaje.

Responder

Alejandro

Muchas gracias por el aporte! justo lo que he estado buscando desde hace ya tiempo

Responder

Con FF 52.0.1 no funciona. Sin problemas con Chrome, IE y Opera, pero con FF simplemente no.

Responder

by Jose M. Alarcon

Pruébalo un poco mejor: funciona perfectamente.

Responder

Ya hice infinidad de pruebas y sólo con Firefox tengo el problema. Si ejecuto algo con javascript justo antes de validar el evento si funciona, pero si cierro la pestaña sin hacer nada que implique javascript entonces simplemente no es detectado.

Repito, eso sólo pasa con FireFox, actualmente uso la versión más reciente 52.0.1. Ya modifiqué el cpodigo para usar listener a evento y es lo mismo. Coloco el evento manualmente o con jquery y es lo mismo.

Responder

by Jose M. Alarcon

Pyes está claro que algo tienes mal en tu código, porque este evento funciona perfectamente en Firefox, incluyendo la última versión (52.0.1). Lo puedes comprobar fácilmente copiando y pegando el código de ejemplo del artículo. Probablemente haces algo en el código de tu evento que no está permitido en Firefox o quizá lo ejecutas en local y por temas de XSS no te lo permite, pero el evento funciona.

Responder

Pues resulta que con tu código tampoco funciona. Lo copio directamente a un archivo prueba.html y lo abro en varios navegadores y aplico la prueba.

Solamente funciona si das click en el botón "Preguntar" y posteriormente cierras la pestaña. Si cierras la pestaña justo después de abrirlo no pregunta ( y se supone que debería preguntar .

Repito la prueba en Chrome, Opera e IE y funciona en el modo default y con el click en el botón "Preguntar".

Con mi código pasa lo mismo, sólo pregunta si se hace algo que mediante evento de javascript (click en un botón) ponga el valor de la variable a validar. Si se coloca un valor default mediante declaración del código simplemente la ignora. Y da igual si esta declaración se hace con javascript o incluso con jQuery

Lo he probado en tres computadoras pensando en configuración modificada del navegador en los equipos, pero obtengo los mismos resultados con los navegadores ya citados.

El default si funciona cuando se da click en la liga, allí si que pregunta por la salida aún cuando no se haya dado click en el botón "Preguntar".

Ojo, el problema no es tu código puesto que he probado otras soluciones encontradas en internet para el mismo evento, y el problema es el mismo aunque se cambie el enfoque.

Responder

by Jose M. Alarcon

A ver... a lo mejor es que no  es tan evidente como parece: todo el objeto del ejemplo es precisamente que le des al botón de preguntar para que te pregunte, para que veas que e fácil activar o desactivar esa funcionalidad. Funciona perfectamente: esa es la idea del ejemplo 😣

Por favor, lee el artículo con calma y verás que "todo encaja". Funciona todo bien y como es de esperar, en todos los navegadores.

Responder

Y entonces para que está el comportamiento default?

"Por defecto preguntará hasta que pulses el botón de "No preguntar""

No es consistente que pongas algo como default si realmente no lo es!

Si la bandera indica de inicio que debe preguntar antes de cerrar esto no se cumple con Firefox, ya que al cerrar lo hace de inmediato ignorando el código establecido.

Y ese comportamiento default funciona perfectamente en otros navegadores, el problema es solo con Firefox, y ya ví que no soy el único con ese caso, hay docenas de reportes del mismo problema.

Gracias por las respuestas, pero no es satisfactorio el resultado.

Responder

by Jose M. Alarcon

Bueno, ahora te has explicado un poco mejor.

Firefox, por defecto, no muestra ese mensaje si no ha habido ninguna interacción entre el usuario y la página. Es decir, si no pulsas en algo (no tiene que ser un botón) o mueves la página, o haces cualquier cosa, no muestra el mensaje. Basta con que pulses en cualquier lado o interacciones de la manera que sea (por ejemplo presionar una tecla en tu teclado o pulsar un enlace, lo que sea) con la página para que ya funcione.

Eso no es un problema: es así por diseño. Y es que todo el objeto de este evento es evitar que se pierdan cambios que hayas hecho en la página, no impedir que los usuarios se vayan (sino no lo preguntaría tampoco). Si ni siquiera ha habido la más mínima interacción, entonces ¿qué objeto tiene mostrar ese mensaje?.

De hecho este comportamiento solo te afectaría si abres la página y antes de hacer absolutamente nada, la cierras. Así que tampoco supone un problema ¿no?

Pruébalo y veras que es así. Eso no es cosa de la última versión de Firefox, sino que ha sido así durante bastante tiempo (no sé precisarte cuánto).

El código funciona perfectamente por tanto.

Responder

Gracias por la respuesta.

Lo he podido comprobar. Desde un par de mensajes antes ya te había señalado que no se trataba de un problema en el código.

Conoces la referencia técnica donde se especifica esa funcionalidad de Firefox?

Es interesante saber porque ellos lo definen así cuando en todos los demás navegadores no es obligatoria la interacción para que se gatille el evento.

Responder

Marcos Torres

Es muy útil el aporte.

He leído todos los comentarios que me anteceden y comento lo siguiente.

Es muy importante saber varias cosas.

1.-que necesito
2.-que  busco
3.-lo que encuentro, que tan cercano es a lo que necesito
4.-como funciona para saber entender el propósito u objetivo para lo que esta hecho.

Comento esto por que el titulo del post "TRUCO: Cómo detectar el cierre o la salida de una página Web " es para identificar el evento del cierre de una pagina y no como hacer eventos antes de cerrar la pagina, a demás es muy importante saber que herramientas estoy utilizando para el desarrollo de una pagina, así como, la metodología que se utilizara.

Ejemplo.
Si utilizan .NET con eventos de controles de servidor, el truco jamás funcionara, por que los eventos de servidor, realizan una recarga de información "postback" pero previo a esto, es una descarga de información "en ese momento se ejecuta el evento ya mencionado onbeforeunload, por sonsiguiente, jamas podrán controlar la salida real de una pagina, ya que cualquier control que tenga un evento del lado del servidor, probocara el postback,

Pero si los eventos son del lado de HTML, bien controlados, entonces el truco funciona perfectamente, por que son eventos de JavaScript y toda la programación es por HTML y JavaScript, si agregan jquery, o cualquier lenguaje que se utilice para una pagina que no tenga que ver con eventos de servidor, el truco funciona perfectamente bien.

Entonces es indispensable saber como funcionan las herramientas "Que estoy utilizando", para saber contestar las preguntas con las que inicie mi comentario.

Les recomiendo sigan esas preguntas para encontrar lo que requieren.


Responder

Mira las cosas de la vida, buscando de nuevo mas informacion sobre este tema, nuestro gran amigo Jose M. Alarcon tiene otro blog, que sin utilizar JQuery, puedes detectar los estados de la carga de la pagina, que junto con el evento window.onbeforeunload puede solucionar gran parte de los comentarios de este blog. Yo he actualizado mis escripts y ahora funiona justo como yo quiero. Manaña publicare mi blog con el widget que he hecho para lanzar el tipico icono de cargando cuando se entre o se sale de la pagina. Un saludo aqui dejo el enlace con la informacion de Jose M. Alarcon que escribio poco despues de este blog.

www.jasoft.org/.../...agina-actual-esta-lista.aspx

Responder

Lo prometido es deuda. Aqui tienen el blog con el widget que he hecho en JAVASCRIPT. Tienen todo el codigo visible y pueden descargarlo tambien

beginners.net.community-mall.com/.../?

Espero que les ayude.

Responder

dioni hidalgo

Excelente codigo, otra opcion que seria de mucha ayuda seria el poder saber cual es el resultado de la alerta que se le presenta el usuario, para que en caso de selecionar k desea salir tener todos los datos almacenados en bases de datos con tablas temporales y asu vez limpiarlos y no tener datos inecesarios en la db...

Responder

Hola, muy bueno tu blog.

Me surgió una pregunta luego de leer tu artículo:

Si teniendo el siguiente codigo JS:

  $.ajax({url:'index.php?id=9', cache:false, type:'post',data:dat,
    beforeSend: function(){
      $("#loading-div-background").css({ opacity: .9 });
      $("#loading-div-background").show();
    },
    success: function(data){
      
      $("#loading-div-background").hide();
      var alto = screen.height-350;
      var ancho = screen.width-1600;
      $('#frm_show2').html(data).dialog({
        modal:true,
        width:'auto',
        height:alto,    
        resizable: true,            
        title:"Detalle Nro Proceso "+nroProceso,            
        open:function(event,ui){
          $(event.target).parent().css('top','10px');
          $(event.target).parent().css('left','180px');},
          
      })
    }
  })

Y deseo saber en que momento el usuario cerrarrá esta ventana emergente para realizar otra acción, como podria saberlo?

Saludos.

Responder

Hola que tal excelente aporte gracias, de casualidad se puede también capturar los valores de los alert para poder cerrar una sesión de usuario en el caso de dar salir?

Responder

Agregar comentario