2008-12-02 21 views
49

He probado el siguiente código para obtener una alerta al cerrar una ventana del navegador:¿Cómo prevenir el cierre de la ventana del navegador?

window.onbeforeunload = confirmExit; 
function confirmExit() { 
    return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?"; 
} 

Funciona, pero si la página contiene un hipervínculo, al hacer clic en hipervínculo que plantea la misma alerta. Necesito mostrar la alerta solo cuando cierro la ventana del navegador y no al hacer clic en hipervínculos.

+2

Votaron para reabrir. El duplicado vinculado no responde la pregunta, pero las respuestas aquí sí. – Heinzi

+0

FWIW, vendré a apuñalarte con el dedo meñique si colocas este comportamiento en cualquier aplicación que tenga que usar. Secuestrar el navegador es una maravillosa solución para este problema. ¿No puedes usar AJAX o algo así y guardar automáticamente su estado? – Graham

+4

No estoy de acuerdo con Graham: a veces, todo lo que necesita es una advertencia/confirmación. De acuerdo, esto puede (y a menudo lo es) ser abusado por sitios que intentan evitar que usted se vaya, pero si se lo emplea correctamente, puede ser muy apreciado, por ejemplo, si olvida publicar algo. – devios1

Respuesta

28

Mantenga su código como está y utilizar jQuery para manejar enlaces:

$(function() { 
    $("a").click(function { 
    window.onbeforeunload = null; 
    }); 
}); 
+0

¿Funciona esto, si la ventana secundaria abierta está en otro dominio? –

+0

Sí, funciona para los enlaces, pero proporcione una solución para cuando actualicemos el navegador la ventana. Antes de descargar el activador de eventos, ¿cómo podemos dejar de activar el evento en la página de actualización o presionando el botón Atrás? ¿Tiene alguna idea sobre esto? –

+5

No hay jQuery etiqueta para esta pregunta. –

45

Otra aplicación es la siguiente se puede encontrar en la página: http://ujap.de/index.php/view/JavascriptCloseHook

<html> 
    <head> 
    <script type="text/javascript"> 
     var hook = true; 
     window.onbeforeunload = function() { 
     if (hook) { 
      return "Did you save your stuff?" 
     } 
     } 
     function unhook() { 
     hook=false; 
     } 
    </script> 
    </head> 
    <body> 
    <!-- this will ask for confirmation: --> 
    <a href="http://google.com">external link</a> 

    <!-- this will go without asking: --> 
    <a href="anotherPage.html" onClick="unhook()">internal link, un-hooked</a> 
    </body> 
</html> 

lo que hace es que usa una variable como una bandera.

+0

+1 porque es una solución más general y accesible. Supongamos que tengo una porción de script que hace que la página se redireccione, por lo que antes de aplicar la acción de redirección, simplemente configuro 'hook = false'. Checkout [** this DEMO **] (http://jsbin.com/fadeso/1/) – SaidbakR

+0

Basado en su solución, propongo que si usa jQuery, use una clase como .noConfirm y haga algo como: $ ('.noConfirm'). clic (desenganchar) –

+0

@netadictos. Te recomiendo que actualices tu respuesta para usar '.addEventListener()' más moderno en lugar del atributo 'onclick' (o' .onbeforeunload = ... '). –

6

Puede detectar hipervínculos clics, pero no se puede determinar si el usuario:

  • trataban de actualizar la página.
  • Se ha intentado cerrar la pestaña del navegador.
  • Se ha intentado cerrar la ventana del navegador.
  • Ingresó otra URL en la barra de la URL y presionó enter.

Todas estas acciones generan beforeunload evento en window, sin ninguna información más exacta sobre el evento.

Con el fin de mostrar diálogo de confirmación cuando se hace por encima de las acciones, y no mostrarlo cuando se hace clic en un hipervínculo, siga estos pasos:

  • Asignar beforeunload detector de eventos a window, que devuelve el texto de confirmación como una cadena, a menos que una variable específica (indicador) esté configurada en true.
  • Asignar click evento al document. Compruebe si se ha hecho clic en el elemento a (event.target.tagName). En caso afirmativo, establezca el indicador en true.

También debe manejar los envíos de formularios mediante la asignación de un oyente submit evento para document.

Su código podría tener este aspecto:

let disableConfirmation = false; 
 
window.addEventListener('beforeunload', event => { 
 
    const confirmationText = 'Are you sure?'; 
 
    if (!disableConfirmation) { 
 
    event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+ 
 
    return confirmationText;    // Gecko, WebKit, Chrome <34 
 
    } else { 
 
    // Set flag back to false, just in case 
 
    // user stops loading page after clicking a link. 
 
    disableConfirmation = false; 
 
    } 
 
}); 
 
document.addEventListener('click', event => { 
 
    if (event.target.tagName.toLowerCase() === 'a') { 
 
    disableConfirmation = true; 
 
    } 
 
}); 
 
document.addEventListener('submit', event => { 
 
    disableConfirmation = true; 
 
});
<p><a href="https://stacksnippets.net/">google.com</a></p> 
 
<form action="https://stacksnippets.net/"><button type="submit">Submit</button></form> 
 
<p>Try clicking the link or the submit button. The confirmation dialog won't be displayed.</p> 
 
<p>Try reloading the frame (right click -> "Reload frame" in Chrome). You will see a confirmation dialog.</p>

Tenga en cuenta que en algunos navegadores que hay que utilizar en event.returnValuebeforeunload oyente, y en otros se utilice return comunicado.

Véase también beforeunload event docs.

Cuestiones relacionadas