Pregunta

Necesito advertir a los usuarios sobre los cambios no guardados antes de que abandonen una página (un problema bastante común).

window.onbeforeunload=handler

Esto funciona pero genera un diálogo predeterminado con un mensaje estándar irritante que envuelve mi propio texto. Necesito reemplazar completamente el mensaje estándar, por lo que mi texto es claro, o (aún mejor) reemplazar todo el cuadro de diálogo con un cuadro de diálogo modal usando jQuery.

Hasta ahora he fallado y no he encontrado a nadie más que parezca tener una respuesta. ¿Es posible?

Javascript en mi página:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

La función closeIt ():

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

Usando jQuery y jqModal He intentado este tipo de cosas (usando un diálogo de confirmación personalizado):

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

que tampoco funciona: parece que no puedo vincularme al evento beforeunload.

¿Fue útil?

Solución

No puede modificar el diálogo predeterminado para onbeforeunload , por lo que su mejor opción es trabajar con él.

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

Aquí hay una referencia a esto de Microsoft :

  

Cuando se asigna una cadena a la propiedad returnValue de window.event, aparece un cuadro de diálogo que ofrece a los usuarios la opción de permanecer en la página actual y conservar la cadena que se le asignó. La declaración predeterminada que aparece en el cuadro de diálogo, "¿Está seguro de que desea salir de esta página? ... Presione OK para continuar, o Cancelar para permanecer en la página actual. & Quot ;, no se puede eliminar ni modificar.

El problema parece ser:

  1. Cuando se llama a onbeforeunload , tomará el valor de retorno del controlador como window.event.returnValue .
  2. Luego analizará el valor de retorno como una cadena (a menos que sea nulo).
  3. Dado que false se analiza como una cadena, se activará el cuadro de diálogo, que luego pasará un true / false apropiado.

El resultado es que no parece haber una forma de asignar false a onbeforeunload para evitar que aparezca en el diálogo predeterminado.

Notas adicionales sobre jQuery:

  • Configurar el evento en jQuery puede ser problemático, ya que eso también permite que ocurran otros eventos onbeforeunload . Si solo desea que su evento de descarga ocurra, me quedaré con JavaScript simple.
  • jQuery no tiene un acceso directo para onbeforeunload , por lo que tendría que usar la sintaxis genérica bind .

    $(window).bind('beforeunload', function() {} );
    

Editar 04/09/2018 : los mensajes personalizados en los cuadros de diálogo onbeforeunload están en desuso desde chrome-51 (cf: nota de lanzamiento )

Otros consejos

Lo que funcionó para mí, usando jQuery y probado en IE8, Chrome y Firefox, es:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

Es importante no devolver nada si no se requiere un aviso, ya que hay diferencias entre IE y otros comportamientos del navegador aquí.

Si bien no hay nada que pueda hacer sobre el cuadro en algunas circunstancias, puede interceptar a alguien haciendo clic en un enlace. Para mí, valió la pena el esfuerzo para la mayoría de los escenarios y, como alternativa, dejé el evento de descarga.

He usado Boxy en lugar del jQuery Dialog estándar, está disponible aquí: http: // onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

Puede adjuntar a otro evento y filtrar más en qué tipo de ancla se hizo clic, pero esto funciona para mí y lo que quiero hacer y sirve como un ejemplo para que otros lo usen o mejoren. Pensé en compartir esto para aquellos que desean esta solución.

He recortado el código, por lo que puede que esto no funcione como está.

1) Use onbeforeunload, no onunload.

2) Lo importante es evitar ejecutar una declaración de devolución. No me refiero, con esto, a evitar regresar de su controlador. Devuelve todo bien, pero lo hace asegurándose de llegar al final de la función y NO ejecuta una declaración de devolución. En estas condiciones, el cuadro de diálogo estándar incorporado no se produce.

3) Puede, si usa onbeforeunload, ejecutar una llamada ajax en su controlador unbeforeunload para ordenar el servidor, pero debe ser síncrono, y debe esperar y manejar la respuesta en su controlador onbeforeunload (aún respetando la condición (2) anterior). Hago esto y funciona bien. Si realiza una llamada ajax síncrona, todo se retiene hasta que vuelva la respuesta. Si hace una asincrónica, pensando que no le importa la respuesta del servidor, la descarga de la página continúa y su proceso cancela su llamada ajax, incluido un script remoto si se está ejecutando.

Intente colocar un return; en lugar de un mensaje ... esto funciona para la mayoría de los navegadores. (Esto realmente solo evita los regalos de diálogo)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

Puede detectar qué botón (ok o cancelar) presionado por el usuario, porque la función de descarga solo se activa cuando el usuario decide salir de la página. Aunque en esta función las posibilidades son limitadas, porque el DOM se está colapsando. Puede ejecutar javascript, pero ajax POST no hace nada, por lo tanto, no puede usar este método para cerrar sesión automáticamente. Pero hay una solución para eso. Window.open ('logout.php') ejecutado en la función de descarga, por lo que el usuario cerrará sesión con una nueva ventana abierta.

function onunload = (){
    window.open('logout.php');
}

Este código se llama cuando el usuario abandona la página o cierra la ventana activa y el usuario cierra sesión con 'logout.php'. La nueva ventana se cierra inmediatamente cuando el cierre de sesión de php consta de código:

window.close();

Me enfrenté al mismo problema, estaba bien para obtener su propio cuadro de diálogo con mi mensaje, pero el problema que enfrenté fue: 1) Estaba dando mensajes en todas las navegaciones. Solo lo quiero para hacer clic cerca. 2) con mi propio mensaje de confirmación si el usuario selecciona cancelar, todavía muestra el cuadro de diálogo predeterminado del navegador.

El siguiente es el código de soluciones que encontré, que escribí en mi página maestra.

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;

Esto no se puede hacer en Chrome ahora para evitar el spam, consulte javascript onbeforeunload no muestra mensaje personalizado para más detalles.

 <script type="text/javascript">
        window.onbeforeunload = function(evt) {
            var message = 'Are you sure you want to leave?';
            if (typeof evt == 'undefined') {
                evt = window.event;
            }       
            if (evt) {
                evt.returnValue = message;
            }
            return message;
        } 
    </script>

consulte http://www.codeprojectdownload.com

¿Qué hay de usar la versión especializada de " bind " comando " uno " ;. Una vez que el controlador de eventos se ejecuta por primera vez, se elimina automáticamente como un controlador de eventos.

$(window).one("beforeunload", BeforeUnload);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top