Cómo mostrar el mensaje "¿Está seguro de que desea salir de esta página?" cuando se cometieron los cambios?

290

Aquí, en stackoverflow, si comenzó a hacer cambios y luego intenta navegar fuera de la página, aparece un botón de confirmación de javascript y pregunta: "¿Está seguro de que desea navegar fuera de esta página?" blee bla bloo ...

¿Alguien ha implementado esto antes, cómo hago un seguimiento de los cambios realizados? Creo que podría hacerlo yo mismo, estoy tratando de aprender las buenas prácticas de ustedes, los expertos.

Intenté lo siguiente pero todavía no funciona:

<html>
<body>
    <p>Close the page to trigger the onunload event.</p>
    <script type="text/javascript">
        var changes = false;        
        window.onbeforeunload = function() {
            if (changes)
            {
                var message = "Are you sure you want to navigate away from this page?\n\nYou have started writing or editing a post.\n\nPress OK to continue or Cancel to stay on the current page.";
                if (confirm(message)) return true;
                else return false;
            }
        }
    </script>

    <input type='text' onchange='changes=true;'> </input>
</body>
</html>

¿Alguien puede publicar un ejemplo?

2
  • 3
    Para que su ejemplo funcione, cambie la función a: myFunction () {window.onbeforeunload = "message"; } luego cambie la entrada: <input type = 'text' onchange = 'myFunction ();'> </input>
    Keith
    13/07/09 a las 15:13
  • Relacionado: stackoverflow.com/q/821011/435605 9 de febrero de 2016 a las 6:17
415

Actualización (2017)

Los navegadores modernos ahora consideran que mostrar un mensaje personalizado es un peligro para la seguridad y, por lo tanto, se ha eliminado de todos ellos. Los navegadores ahora solo muestran mensajes genéricos. Como ya no tenemos que preocuparnos por configurar el mensaje, es tan simple como:

// Enable navigation prompt
window.onbeforeunload = function() {
    return true;
};
// Remove navigation prompt
window.onbeforeunload = null;

Lea a continuación para conocer la compatibilidad con navegadores heredados.

Actualización (2013)

La respuesta original es adecuada para IE6-8 y FX1-3.5 (que es lo que estábamos apuntando en 2009 cuando se escribió), pero ahora está bastante desactualizada y no funcionará en la mayoría de los navegadores actuales; me fui a continuación como referencia.

El window.onbeforeunloadno es tratada constantemente por todos los navegadores. Debería ser una referencia de función y no una cadena (como se indicó en la respuesta original), pero eso funcionará en navegadores más antiguos porque la verificación para la mayoría de ellos parece ser si algo está asignado onbeforeunload(incluida una función que regresa null).

Establece window.onbeforeunloaduna referencia de función, pero en los navegadores más antiguos debe establecer el returnValuedel evento en lugar de simplemente devolver una cadena:

var confirmOnPageExit = function (e) 
{
    // If we haven't been passed the event get the window.event
    e = e || window.event;

    var message = 'Any text will block the navigation and display a prompt';

    // For IE6-8 and Firefox prior to version 4
    if (e) 
    {
        e.returnValue = message;
    }

    // For Chrome, Safari, IE8+ and Opera 12+
    return message;
};

No puede hacer que eso confirmOnPageExithaga la verificación y devuelva un valor nulo si desea que el usuario continúe sin el mensaje. Aún necesita eliminar el evento para activarlo y desactivarlo de manera confiable:

// Turn it on - assign the function that returns the string
window.onbeforeunload = confirmOnPageExit;

// Turn it off - remove the function entirely
window.onbeforeunload = null;

Respuesta original (trabajado en 2009)

Encenderlo:

window.onbeforeunload = "Are you sure you want to leave?";

Para apagarlo:

window.onbeforeunload = null;

Tenga en cuenta que este no es un evento normal, no puede vincularse a él de la forma estándar.

¿Para comprobar los valores? Eso depende de su marco de validación.

En jQuery, esto podría ser algo como (ejemplo muy básico):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});
21
  • 4
    Eso sería algo como: $ ('input: text'). Change (function () {window.onbeforeunload = $ ('input: text [value! = ""]'). Length> 0? "Warning": null ;});
    Keith
    13/07/09 a las 15:07
  • 1
    Para una verificación simple, o puede agregar una validación más compleja en cada cambio
    Keith
    13 de julio de 2009 a las 15:09
  • 1
    Vale la pena señalar que el método 'returnValue' es el único método especificado en el estándar, por lo que no es solo para IE6-8, es para todos los navegadores que cumplen con los estándares (en este caso sin incluir Chrome, Safari y Opera). 23/06/14 a las 19:45
  • 3
    Para detener la alerta al enviar un formulario, utilicé $("#submit_button").click(function() { window.onbeforeunload = null; });. Originalmente usé el evento onclick del botón, pero además de no ser tan agradable, tampoco funcionó con IE8. 14 feb.15 a las 13:00
  • 1
    @ AlikElzin-kilaka no puedes. Si desea cambiar el texto emergente, debe crear su propia ventana emergente personalizada, pero eso no puede bloquear el window.onbeforeunloadevento.
    Keith
    8 de febrero de 2016 a las 15:28
40

El onbeforeunloadMicrosoft-ismo es lo más parecido que tenemos a una solución estándar, pero tenga en cuenta que el soporte del navegador es desigual; por ejemplo, para Opera solo funciona en la versión 12 y posteriores (todavía en beta al momento de escribir este artículo).

Además, para obtener la máxima compatibilidad , debe hacer más que simplemente devolver una cadena, como se explica en Mozilla Developer Network .

Ejemplo: defina las siguientes dos funciones para habilitar / deshabilitar el indicador de navegación (consulte el ejemplo de MDN):

function enableBeforeUnload() {
    window.onbeforeunload = function (e) {
        return "Discard changes?";
    };
}
function disableBeforeUnload() {
    window.onbeforeunload = null;
}

Luego defina una forma como esta:

<form method="POST" action="" onsubmit="disableBeforeUnload();">
    <textarea name="text"
              onchange="enableBeforeUnload();"
              onkeyup="enableBeforeUnload();">
    </textarea>
    <button type="submit">Save</button>
</form>

De esta forma, el usuario solo recibirá una advertencia sobre la navegación si ha cambiado el área de texto y no se le preguntará cuando esté enviando el formulario.

2
20

Para que esto funcione en Chrome y Safari, tendrías que hacerlo así

window.onbeforeunload = function(e) {
    return "Sure you want to leave?";
};

Referencia: https://developer.mozilla.org/en/DOM/window.onbeforeunload

0
18

Con JQuery, esto es bastante fácil de hacer. Dado que puede enlazar a conjuntos.

NO es suficiente hacer el onbeforeunload, solo desea activar la navegación si alguien comenzó a editar cosas.

6
  • 2
    Parece que no puedo llegar a las publicaciones del blog de @jonstjohn. ¿Quizás sea un amigo y nos indique la dirección correcta? :D
    FLGMwt
    2/06/2014 a las 20:19
  • dieciséis
    => 500 Error interno. Es por eso que los enlaces están obsoletos en SO. Voto en contra hasta que se solucione.
    Loïc
    19 de septiembre de 2014 a las 10:15
  • Esta pagina web no esta disponible
    Mateusz
    11 de mayo de 2015 a las 9:21
  • 3
    Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden dejar de ser válidas si cambia la página enlazada.
    bwest
    14/07/2015 a las 20:13
  • 2
    El enlace original de Jon St John estaba roto, así que lo actualicé a la versión Wayback Machine . El contenido del enlace se puede encontrar copiado en muchos otros sitios, pero supongo que era mejor "preservar" el que Sam agregó. 15/07/2015 a las 18:36
14

jquerys 'beforeunload' funcionó muy bien para mí

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});
1
12

para las personas nuevas que buscan una solución simple, simplemente pruebe Areyousure.js

11

Esta es una manera fácil de presentar el mensaje si se ingresa algún dato en el formulario, y no mostrar el mensaje si se envía el formulario:

$(function () {
    $("input, textarea, select").on("input change", function() {
        window.onbeforeunload = window.onbeforeunload || function (e) {
            return "You have unsaved changes.  Do you want to leave this page and lose your changes?";
        };
    });
    $("form").on("submit", function() {
        window.onbeforeunload = null;
    });
})
0
8

Para ampliar la ya asombrosa respuesta de Keith :

Mensajes de advertencia personalizados

Para permitir mensajes de advertencia personalizados, puede envolverlos en una función como esta:

function preventNavigation(message) {
    var confirmOnPageExit = function (e) {
        // If we haven't been passed the event get the window.event
        e = e || window.event;

        // For IE6-8 and Firefox prior to version 4
        if (e)
        {
            e.returnValue = message;
        }

        // For Chrome, Safari, IE8+ and Opera 12+
        return message;
    };
    window.onbeforeunload = confirmOnPageExit;
}

Luego simplemente llame a esa función con su mensaje personalizado:

preventNavigation("Baby, please don't go!!!");

Habilitando la navegación de nuevo

Para volver a habilitar la navegación, todo lo que necesita hacer es configurar window.onbeforeunloada null. Aquí está, envuelto en una pequeña función ordenada que se puede llamar en cualquier lugar:

function enableNavigation() {
    window.onbeforeunload = null;
}

Usando jQuery para vincular esto para formar elementos

Si usa jQuery, esto se puede vincular fácilmente a todos los elementos de un formulario como este:

$("#yourForm :input").change(function() {
    preventNavigation("You have not saved the form. Any \
        changes will be lost if you leave this page.");
});

Luego, para permitir que se envíe el formulario:

$("#yourForm").on("submit", function(event) {
    enableNavigation();
});

Formas modificadas dinámicamente:

preventNavigation()y enableNavigation()se puede vincular a cualquier otra función según sea necesario, como modificar dinámicamente un formulario o hacer clic en un botón que envía una solicitud AJAX. Hice esto agregando un elemento de entrada oculto al formulario:

<input id="dummy_input" type="hidden" />

Luego, cada vez que quiero evitar que el usuario se aleje, activo el cambio en esa entrada para asegurarme de que preventNavigation()se ejecute:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

    // ...
    $("#dummy_input").trigger("change");
    // ...
}
3

Aquí prueba esto funciona al 100%

<html>
<body>
<script>
var warning = true;
window.onbeforeunload = function() {  
  if (warning) {  
    return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";  
    }  
}

$('form').submit(function() {
   window.onbeforeunload = null;
});
</script>
</body>
</html>
3

El estándar establece que la solicitud se puede controlar cancelando el evento antes de la descarga o estableciendo el valor de retorno en un valor no nulo . También establece que los autores deben usar Event.preventDefault () en lugar de returnValue, y el mensaje que se muestra al usuario no es personalizable .

A partir de 69.0.3497.92, Chrome no ha cumplido con el estándar. Sin embargo, se ha presentado un informe de error y se está realizando una revisión . Chrome requiere que returnValue se establezca por referencia al objeto de evento, no al valor devuelto por el controlador.

Es responsabilidad del autor hacer un seguimiento de si se han realizado cambios; se puede hacer con una variable o asegurándose de que el evento solo se maneje cuando sea necesario.

window.addEventListener('beforeunload', function (e) {
    // Cancel the event as stated by the standard.
    e.preventDefault();
    // Chrome requires returnValue to be set.
    e.returnValue = '';
});
    
window.location = 'about:blank';
2

Cuando el usuario comience a realizar cambios en el formulario, se establecerá una bandera booleana. Si el usuario intenta salir de la página, verifica esa marca en el evento window.onunload . Si la bandera está configurada, muestra el mensaje devolviéndolo como una cadena. Al devolver el mensaje como una cadena, aparecerá un cuadro de diálogo de confirmación que contiene su mensaje.

Si está utilizando ajax para confirmar los cambios, puede establecer la bandera en falsedespués de que se hayan confirmado los cambios (es decir, en el evento de éxito de ajax).

1

Puede agregar un onchangeevento en el área de texto (o cualquier otro campo) que establezca una variable en JS. Cuando el usuario intenta cerrar la página (window.onunload), verifica el valor de esa variable y muestra la alerta en consecuencia.

1
  • 1
    No puede hacer esto, alerty confirmestá bloqueado durante window.onbeforeunloady window.onunload(al menos en la versión de Chrome en mi PC, pero probablemente también en todos los navegadores para admitir esos controladores). 17/07/2013 a las 19:56
1

Basado en todas las respuestas en este hilo, escribí el siguiente código y funcionó para mí.

Si solo tiene algunas etiquetas de entrada / área de texto que requieren que se verifique un evento de descarga, puede asignar atributos de datos HTML5 como data-onunload="true"

por ej.

<input type="text" data-onunload="true" />
<textarea data-onunload="true"></textarea>

y el Javascript (jQuery) puede verse así:

$(document).ready(function(){
    window.onbeforeunload = function(e) {
        var returnFlag = false;
        $('textarea, input').each(function(){
            if($(this).attr('data-onunload') == 'true' && $(this).val() != '')
                returnFlag = true;
        });

        if(returnFlag)
            return "Sure you want to leave?";   
    };
});
1
  • 2
    Consulte también "Por algunas razones, los navegadores basados ​​en Webkit no siguen las especificaciones del cuadro de diálogo" en la documentación de MDN antes de descargar .
    Arjan
    26 feb 2013 a las 19:17
1

aquí está mi html

<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>

 <body onload="myFunction()">
    <h1 id="belong">
        Welcome To My Home
    </h1>
    <p>
        <a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
    </p>
</body>

Y así es como hice algo similar en javaScript

var myGlobalNameHolder ="";

function myFunction(){
var myString = prompt("Enter a name", "Name Goes Here");
    myGlobalNameHolder = myString;
    if (myString != null) {
        document.getElementById("replaceME").innerHTML =
        "Hello " + myString + ". Welcome to my site";

        document.getElementById("belong").innerHTML =
        "A place you belong";
    }   
}

// create a function to pass our event too
function myFunction2(event) {   
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
    x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}
0

Se puede hacer fácilmente estableciendo un ChangeFlag en verdadero, en el evento onChange de TextArea . Use javascript para mostrar el cuadro de diálogo de confirmación basado en el valor de ChangeFlag . Descarte el formulario y navegue a la página solicitada si la confirmación devuelve verdadero, de lo contrario, no haga nada .

0

Lo que desea utilizar es el evento onunload en JavaScript.

Aquí hay un ejemplo: http://www.w3schools.com/jsref/event_onunload.asp

0
0

Desde WebAPIs-> WindowEventHandler-> onbeforeunload , recomienda usar window.addEventListener()y el beforeunloadevento, en lugar de onbeforeunload.

Ejemplo de sintaxis

window.addEventListener("beforeunload", function(event) { ... });
window.onbeforeunload = function(event) { ... };

Nota: La especificación HTML establece que los autores deben usar el Event.preventDefault()método en lugar de usar Event.returnValuepara solicitar al usuario.

Entonces, en términos de su caso, el código debería verse así:

//javascript
window..addEventListener("beforeunload", function(event) { 
    //your code

    // If you prevent default behaviour in Mozilla Firefox prompt will always be shown
    e.preventDefault();

    // Chrome requires returnValue to be set
    e.returnValue = '';
})
-1

Hay un parámetro "onunload" para la etiqueta del cuerpo que puede llamar a las funciones de JavaScript desde allí. Si devuelve falso, evita la navegación.

1
  • 13
    Afortunadamente, esto no funciona. De lo contrario, odiaría visitar una página que contenga <body onunload="return false;">. 13/07/09 a las 13:29