pagina - javascript detectar cierre pestaña
Detectar navegador o cierre de pestañas (18)
¿Hay algún código JavaScript / jQuery en todos los navegadores para detectar si el navegador o una pestaña del navegador se está cerrando, pero no debido a que se haga clic en un enlace?
Como mencionó @jAndy, no hay un código javascript adecuado para detectar una ventana que se está cerrando. Comencé por lo que @Syno había propuesto.
Pasé por una situación así y, si sigues estos pasos, podrás detectarlo.
Lo probé en Chrome 67+ y Firefox 61+.
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on(''focus'', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on(''blur'', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on(''resize'', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off(''resize''); //avoid multiple listening
});
$(''html'').on(''mouseleave'', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he''s
//leaving or thinking about closing the window
});
$(''html'').on(''mouseenter'', function () {
closing_window = false;
//if the user''s mouse its on the page, it means you don''t need to logout
//them, didn''t it?
});
$(document).on(''keydown'', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: ''/MyController/MyLogOutAction'',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
De la documentación de Firefox
Por algunas razones, los navegadores basados en Webkit no siguen la especificación para el cuadro de diálogo. Un ejemplo casi cruzado estaría cerca del siguiente ejemplo.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "/o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
Este ejemplo para manejar todos los navegadores.
Encontré una forma que funciona en todos mis navegadores .
Probado en las siguientes versiones: Firefox 57, Internet Explorer 11, Edge 41, uno de los últimos Chrome (no mostrará mi versión)
Nota : antes de descargar se dispara si abandona la página de cualquier forma posible (actualizar, cerrar navegador, redirigir, vincular, enviar ...). Si solo desea que ocurra en el cierre del navegador, simplemente enlace los controladores de eventos.
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal refresh)
$(document).bind(''keypress'', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
Es posible verificarlo con la ayuda de window.closed en un controlador de eventos en el evento ''descargar'', pero se requiere un tiempo de espera (por lo que no se puede garantizar el resultado si se produce un retraso o si se evita el cierre de la ventana):
Ejemplo de JSFiddle (Probado en lates Safari, FF, Chrome, Edge e IE11)
var win = window.open('''', '''', ''width=200,height=50,left=200,top=50'');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener(''load'',() => {
document.querySelector(''.status'').innerHTML += ''<p>Child was loaded!</p>'';
});
win.addEventListener(''unload'',() => {
document.querySelector(''.status'').innerHTML += ''<p>Child was unloaded!</p>'';
setTimeout(()=>{
document.querySelector(''.status'').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector(''.check-child-window'').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return ''Child window has been closed!'';
} else {
return ''Child window has not been closed!'';
}
}
Lo sentimos, no pude agregar un comentario a una de las respuestas existentes, pero en caso de que quisiera implementar un tipo de diálogo de advertencia, solo quería mencionar que cualquier función de controlador de eventos tiene un argumento - evento. En su caso, puede llamar a event.preventDefault () para no permitir que la página salga automáticamente, luego emita su propio cuadro de diálogo. Considero que esta es una opción mucho mejor que usar la alerta feo e insegura () estándar. Personalmente implementé mi propio conjunto de cuadros de diálogo basados en el objeto kendoWindow (la interfaz de usuario de Kendo de Telerik, que es casi totalmente de código abierto, excepto kendoGrid y kendoEditor). También puede utilizar cuadros de diálogo de jQuery UI. Sin embargo, tenga en cuenta que tales cosas son asíncronas, y tendrá que vincular un controlador para hacer clic en el evento de cada botón, pero todo esto es muy fácil de implementar.
Sin embargo, estoy de acuerdo en que la falta del evento de cierre real es terrible: si, por ejemplo, desea restablecer el estado de su sesión en el back-end solo en el caso del cierre real, es un problema.
Necesitaba cerrar sesión automáticamente cuando el navegador o la pestaña se cierran, pero no cuando el usuario navega a otros enlaces. Tampoco quería que se mostrara un mensaje de confirmación cuando eso sucediera. Después de luchar con esto por un tiempo, especialmente con IE y Edge, esto es lo que terminé haciendo (verifiqué el trabajo con IE 11, Edge, Chrome y Firefox) después de basarme en el enfoque con esta respuesta .
Primero, inicie un temporizador de cuenta regresiva en el servidor en el controlador de eventos de beforeunload
en JS. Las llamadas ajax deben ser sincrónicas para que IE y Edge funcionen correctamente. También es necesario utilizar return;
para evitar que el diálogo de confirmación se muestre así:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
Al iniciar el temporizador se establece el indicador cancelLogout
en falso . Si el usuario actualiza la página o navega a otro enlace interno, el indicador cancelLogout
en el servidor se establece en verdadero . Una vez que transcurre el evento del temporizador, verifica el indicador cancelLogout
para ver si el evento de cierre de sesión se ha cancelado. Si el temporizador ha sido cancelado, entonces lo detendría. Si se cerró el navegador o la pestaña, el indicador cancelLogout
permanecerá falso y el controlador de eventos cerrará la sesión del usuario.
Nota de implementación: estoy usando ASP.NET MVC 5 y estoy cancelando el cierre de sesión en un método de Controller.OnActionExecuted()
invalidado.
No hay evento, pero hay una propiedad window.closed
que es compatible con todos los navegadores principales en el momento de esta escritura. Por lo tanto, si realmente necesita saber que puede sondear la ventana para verificar esa propiedad.
if(myWindow.closed){do things}
Nota: Encuestar cualquier cosa generalmente no es la mejor solución. El evento window.onbeforeunload
se debe usar si es posible, la única advertencia es que también se dispara si se aleja.
Para tareas similares, puede usar sessionStorage
para almacenar datos localmente hasta que se cierre la pestaña del navegador.
El objeto sessionStorage
almacena datos para una sola sesión (los datos se eliminan cuando se cierra la pestaña del navegador). ( w3schools.com/jsref/prop_win_sessionstorage.asp )
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
Prueba esto, estoy seguro de que esto funcionará para ti.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type=''text/javascript''>
$(function() {
try{
opera.setOverrideHistoryNavigationMode(''compatible'');
history.navigationMode = ''compatible'';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind(''beforeunload'', ReturnMessage);
}
$(window).bind(''beforeunload'',ReturnMessage );
});
</script>
Prueba esto. Funcionará. El método de descarga jquery está en desuso.
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};
Si te recibo correctamente, quieres saber cuándo se cierra efectivamente una pestaña / ventana. Bueno, AFAIK es la única forma en Javascript
de detectar que ese tipo de cosas se onbeforeunload
eventos de onunload
y onbeforeunload
.
Desafortunadamente (o, afortunadamente,), esos eventos también se activan cuando deja un sitio a través de un link
o el botón de retroceso de su navegador. Así que esta es la mejor respuesta que puedo dar, no creo que puedas detectar de forma nativa un close
puro en Javascript. Corrígeme si me equivoco aquí.
Solución simple
window.onbeforeunload = function () {
return "Do you really want to close?";
};
$(window).unload( function () { alert("Bye now!"); } );
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = ''You have closed the browser. Do you want to logout from your application?'';
setTimeout(''myclose=false'',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace(''/contextpath/j_spring_security_logout'') ;
}
}
// Esto funciona en IE7, si está cerrando la pestaña o el navegador con una sola pestaña
<script type="text/javascript" language="Javascript">
function DetectBrowserExit()
{
alert(''Execute task which do you want before exit'');
}
window.onbeforeunload = function(){ DetectBrowserExit(); }
</script>
He probado este script en los siguientes navegadores web: en este momento, el navegador web Opera no admite el evento onBeforeUnload. Internet Explorer Mozilla Firefox Google Chrome Safari
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
Esta función muestra un cuadro de diálogo de confirmación si cierra la ventana o actualiza la página durante cualquier proceso en el navegador. Esta función funciona en todos los navegadores. Debe configurar isProcess var en su proceso ajax.
window.onbeforeunload = function() {
console.log(''event'');
return false; //here also can be string, that will be shown to the user
}