2009-02-20 11 views
29

Cuando actualizamos la página (F5, o icono en el navegador), primero activa el evento ONUNLOAD. Cuando cerramos el navegador (X en el icono superior derecho), se activará el evento ONUNLOAD . Ahora cuando se desencadena el evento ONUNLOAD, no hay forma de distinguir entre actualizar la página o cerrar el navegador. Si tienes alguna solución, dame.Identificación entre acciones de navegador de actualización y cierre

+0

Consulte también para preguntas similares: http://stackoverflow.com/questions/4387212/differentiate-between-f5-and-browser-close-event-in-flex-actionscript y http://stackoverflow.com/questions/1631959/browser-window-close-event –

+0

Aquí está la respuesta de cómo detectar la recarga de la página a través de api HTML5 en los navegadores MODERN. (Funciona para mí): https://stackoverflow.com/questions/5004978/check-if-page -gets-reloaded-or-refreshed-in-javascript –

Respuesta

-6
<html> 
<body onunload="doUnload()"> 
<script> 
    function doUnload(){ 
    if (window.event.clientX < 0 && window.event.clientY < 0){ 
     alert("Window closed"); 
    } 
    else{ 
     alert("Window refreshed"); 
    } 
    } 
</script> 
</body> 
</html> 
+0

¿Funciona en todos los navegadores? por favor dame algunos comentarios. –

+0

Gracias amigo, pero su código no funciona, navegador FF, así que por favor sugiera otra respuesta. –

+0

por favor vea la otra respuesta. debería funcionar para usted. si funciona, marque la respuesta como correcta para que otros lo sepan. –

-2

Mi solución anterior funcionó para mí en IE. window.event no estaría definido para navegadores que no sean IE ya que 'evento' está definido globalmente en IE a diferencia de otros navegadores. Debería proporcionar evento como parámetro en el caso de otros navegadores. Además ese clientX no está definido para firefox, deberíamos usar pageX.

intentar algo como esto .... debe trabajar para IE y Firefox esto ...

<html> 
<body> 
<script type="text/javascript"> 

window.onunload = function(e) { 
// Firefox || IE 
e = e || window.event; 

var y = e.pageY || e.clientY; 

if(y < 0) alert("Window closed"); 
else alert("Window refreshed"); 

} 
</script> 
</body> 
</html> 
+0

gracias Liv 1, probé este código pero no funciona correctamente en Firefox, en este problema se produce cuando se cierra la pestaña y se hace clic en el botón actualizar. Si tiene alguna otra solución, por favor, por favor ... –

+0

@renegadeMind, ¿le funcionó? –

+3

Esta técnica no se puede usar para determinar de manera confiable si la ventana del navegador se ha cerrado. –

6

inspeccionar Desafortunadamente el valor clientY/pageY del evento, según lo sugerido por algunas de las respuestas aquí, es no es una forma confiable de determinar si el evento unload se está activando como consecuencia de que el usuario cierre la página.

La razón clientY/pageY es negativo cuando se hace clic en el botón de cierre del navegador se debe a que el botón de cierre se coloca por encima de la parte superior del documento (es decir, por encima de píxeles 0), pero también lo es el significado botón de recarga que haga clic en el botón de recarga también dará como resultado un valor negativo para clientY/pageY.

Ir por el camino de inspeccionar la coordenada x del evento también es problemático porque el botón de cierre del navegador no siempre está en el lado derecho de la ventana (por ejemplo, está a la izquierda en OS X) y porque la ventana se puede cerrar al cerrar su pestaña o mediante el teclado.

39

Hay una solución.

Quería desconectar al usuario del servidor cuando se cerró la pestaña o la ventana del navegador, pero no cuando la página se recargó (es posible que desee diferenciar eventos de recarga/cierre para un propósito diferente pero puede beneficiarse de mi solución) Terminé con el siguiente proceso, basado en el almacenamiento y el cliente AJAX/servidor local de comunicación de HTML5:

  1. en su página, añadir una onunload a la window a la siguiente controlador (pseudo-javascript):

    function myUnload(event) { 
        if (window.localStorage) { 
         // flag the page as being unloading 
         window.localStorage['myUnloadEventFlag']=new Date().getTime(); 
        } 
    
        // notify the server that we want to disconnect the user in a few seconds (I used 5 seconds) 
        askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call 
    } 
    
  2. en su página, añadir un onload en el body a la siguiente controlador (pseudo-javascript):

    function myLoad(event) { 
        if (window.localStorage) { 
         var t0 = Number(window.localStorage['myUnloadEventFlag']); 
         if (isNaN(t0)) t0=0; 
         var t1=new Date().getTime(); 
         var duration=t1-t0; 
         if (duration<10*1000) { 
          // less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request) 
          askServerToCancelDisconnectionRequest(); // asynchronous AJAX call 
         } else { 
          // last unload event was for a tab/window close => do whatever you want (I do nothing here) 
         } 
        } 
    } 
    
  3. en el servidor, recoger las solicitudes de desconexión en una lista y establecer un hilo de temporizador que inspecciona la lista a intervalos regulares (utilicé cada 20 segundos). Una vez que se agota el tiempo de espera de la solicitud de desconexión (es decir, se han agotado los 5 segundos), desconecte al usuario del servidor. Si se recibe una cancelación de solicitud de desconexión mientras tanto, la solicitud de desconexión correspondiente se elimina de la lista, de modo que el usuario no se desconectará.

Este enfoque también es aplicable si desea diferenciar entre el evento de cierre de pestaña/ventana y los enlaces seguidos o el formulario enviado. Solo debe colocar los dos controladores de eventos en cada página que contiene enlaces y formularios, y en cada enlace/página de inicio de formulario.

Nota que utilizo el evento unload en lugar del evento beforeUnload con el fin de gestionar los enlaces a los archivos adjuntos correctamente: cuando un usuario hace clic en un vínculo a un archivo adjunto (por ejemplo, archivos PDF), el evento beforeUnload se envía, a continuación, un proceso abierto/save popup se genera, y nada más (el navegador no cambia la página mostrada y no envía el evento unload). Si estuviera usando el evento beforeUnload (como lo hice antes), habría detectado un cambio de página cuando no lo hay.

Este enfoque está limitado a los navegadores compatibles con almacenamiento local HTML5, por lo que probablemente utilizaría enfoques específicos para navegadores antiguos como MSIE7.

Otros enfoques basados ​​en event.clientY no son confiables porque este valor es negativo al hacer clic en los botones de recarga o cerrar ficha/ventana, y es positivo cuando se usan los atajos de teclado para volver a cargar (por ejemplo, F5, Ctrl-R, ...) y cierre de ventana (por ejemplo, Alt-F4). Depender de la posición X del evento tampoco es confiable porque los botones no se colocan en la misma posición en cada navegador (por ejemplo, botón Cerrar a la izquierda).

+2

Usaría 'sessionStorage' en lugar de' localStorage' ya que solo está rastreando recargas, no hay razón para que persista. –

+1

Aquí está la respuesta de cómo detectar la recarga de la página a través de api HTML5 en los navegadores MODERN. (Funciona para mí): https://stackoverflow.com/questions/5004978/check-if-page-gets-reloaded-or-refreshed-in -javascript –

+1

@RajabShakirov esta respuesta no se aplica a la detección de la actualización durante el evento de descarga. – cdonner

0

Utilice el evento window.onbeforeunload para el caso para navegar fuera de la página, pero incluirá etiquetas de actualización o de anclaje ... use un indicador de validación para el mismo, 1 ejemplo para el proceso es la verificación URL (Initial URL = URL actual) o F5 comprueba utilizando el código clave para actualizar, En caso de etiquetas de anclaje utilice bind()

Nota * El código clave puede causar problemas en el caso de Chrome.

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 
<title>Test Page</title> 

<style type='text/css'> 
body { 
    font-family: sans-serif; 
} 
</style> 
<script src="jquery-1.9.1.js" type='text/javascript'></script> 
<script type='text/javascript'> 
var valid=false; 
function wireUpEvents() { 

if(valid){ 
alert("Page Refreshed or Redirected"); 
}else{ 

window.onbeforeunload = askWhetherToClose; 

} 
function askWhetherToClose(event) { 

if(!valid){ 

    var msg; 

    msg = "You're leaving the page, do you really want to?"; 
    event = event || window.event; 
    event.returnValue = msg; 
    return msg; 
}} 
$(document).bind('keypress', function(e) { 
if (e.keyCode == 116){ 

// or you can insert some code to check page refresh 
valid = true; 

//wireUpEvents(); 
} 
}); 
$("a").bind("click", function() { 
//To check redirection using Anchor tags 
valid = true; 
//wireUpEvents(); 
}); 
} 
$(document).ready(function() { 
wireUpEvents(); 

}); 
</script> 
</head> 
<body> 
<p>Close the browser window, or navigate to <a href="http://stackoverflow.com">StackOverflow</a></p> 
</body> 
</html> 
+1

Este código no funciona cuando un usuario hace clic en el botón de búsqueda o retroceso. – SwR

0

Acabo de intentar esto y se solucionó el problema: Crear un objeto sessionStorage que se destruyen cuando el usuario cierra el navegador. Podemos verificar el objeto sessionStorage para encontrar si el usuario ha cerrado el navegador o actualizado la página (el objeto sessionStorage no se destruirá al actualizar la página).

+1

Esta respuesta necesita un ejemplo de código. En Chrome 56 sessionStorage.getItem() funciona normalmente en onunload oyente cuando el usuario cierra un navegador. –

+0

estableciendo un objeto localStorage trabajado para mí incluso en una versión anterior de IE –

0
$(window).bind('unload', function() { 
     if (/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) { 
      console.log('firefox delete'); 
      var data = { async: false }; 
      endSession(data); 
      return null; 
     } 
     else { 
      console.log('NON-firefox delete'); 
      var data = { async: true }; 
      endSession(data); 
      return null; 
     } 
    }); 

    function endSession(data) { 
     var id = 0 

     if (window) { // closeed 
      id=1 
     } 

     $.ajax({ 
      url: '/api/commonAPI/'+id+'?Action=ForceEndSession', 
      type: "get", 
      data: {}, 
      async: data.async, 
      success: function() { 
       console.log('Forced End Session'); 
      } 
     }); 
    } 

Use if (ventana) para determinar si está cerrado o simplemente vuelva a cargar. trabajando para mi

+0

En Chrome 56 objeto de ventana se define en onunload oyente cuando el usuario cierra un navegador –

0

Hoy tuve el mismo problema y encontré una posible solución que quiero compartir con usted.

Al pensar en lo que podría ayudar a discernir entre la actualización y el cierre, las cookies se me vinieron a la mente. Recuerdo que establecer una cookie sin una fecha de caducidad explícita, la hace disponible solo para la sesión actual. Y una sesión actual es claramente válida hasta que se cierre el navegador. Esto no incluye cerrar una pestaña, pero mi problema era sobre la autenticación de usuario y no quería cerrar la sesión del usuario solo por haber cerrado una pestaña (creo que es el mismo enfoque que la cookie ASPXAUTH de ASP.NET).

Así que puse una cookie simple en la colección document.cookies cuando el usuario inició sesión y la revisó al cargar la página: si la cookie aún estaba allí, era una actualización o una pestaña reabierta y los datos del usuario se guardaban, si la cookie no estaba presente la sesión había expirado, por lo que los datos del usuario se borraron (lo mismo que un cierre de sesión explícito).

Espero que este enfoque pueda ser útil para otra persona.

Cuestiones relacionadas