2009-11-26 25 views
5

Estoy creando una ventana emergente que tiene instalado un controlador de acceso anticipado. Cuando se utiliza el elemento de menú "Cerrar" archivo para cerrar la ventana emergente, se llama al manejador beforeunload dos veces, lo que da como resultado dos "¿Está seguro de que desea cerrar esta ventana?" mensajes que aparecen.window.beforeunload llamado dos veces en Firefox: ¿cómo evitar esto?

Este es un error con Firefox, y tengo reported it here, pero todavía me gustaría una manera de evitar que esto suceda. ¿Puedes pensar en una forma sensata de detectar double beforeunload para evitar el problema del doble mensaje? El problema es que Firefox no me dice en qué botón del diálogo el usuario eligió hacer clic: Aceptar o cancelar.

+0

Error relacionado con la ventana * any *, no solo las ventanas emergentes: [Error 305085 - onbeforeunload muestra "¿De verdad quieres cerrar? - mensaje dos veces] (https://bugzilla.mozilla.org/show_bug.cgi?id= 305085). Inaugurado en 2005, sigue sucediendo en el último Firefox. – Arjan

Respuesta

0

Crea una variable global que se establece en true dentro del controlador. Solo muestre la alerta/ventana emergente cuando esta variable sea falsa.

+0

¿Pero qué pasa si el usuario cancela el cierre? Luego, la próxima vez que intenten cerrar la ventana, el diálogo no aparecerá en absoluto. – Zarkonnen

+0

Si está utilizando 'confirm()' para el mensaje de advertencia, puede detectar si el usuario canceló el cierre y establecer la var global en consecuencia. – leepowers

+0

Pero, ¿cómo abortaría el proceso de cierre en ese punto? – Zarkonnen

1

Establezca una variable en el controlador para evitar que el diálogo aparezca por segunda vez. Use setTimeout para restablecerlo después.

+0

¿Qué es un valor de tiempo de espera razonable? Establecerlo demasiado corto y los usuarios lentos terminarán viendo el diálogo dos veces después de todo. Establecerlo demasiado tiempo y los usuarios rápidos no verán un diálogo en absoluto, lo cual es algo que realmente no debería suceder, ya que podría hacer que pierdan datos. – Zarkonnen

+0

Probablemente puedas hacerlo realmente corto. Supongo que las dos llamadas a beforeunload están separadas por unos pocos milisegundos. Establezca el tiempo de espera en 100 ms o menos, y Boone sabrá que está allí. –

+0

Sin embargo, la segunda llamada vendrá siempre que el usuario haya presionado el botón "Aceptar" en el primer cuadro de diálogo. – Zarkonnen

2
<script type="text/javascript"> 
var onBeforeUnloadFired = false; 

window.onbeforeunload = function() 
{ 
    if (!onBeforeUnloadFired) { 
     onBeforeUnloadFired = true; 
     event.returnValue = "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?"; 
    } 

    window.setTimeout("ResetOnBeforeUnloadFired()", 10); 
} 

function ResetOnBeforeUnloadFired() { 
    onBeforeUnloadFired = false; 
}  
</script> 
0

utilizo el siguiente fragmento de rastrear la exitcount

Cuando la página se carga la siguiente exitCount variable se inicializa

if (typeof(MTG) == 'undefined') MTG = {}; 
MTG.exitCount=0; 

y en el evento de descarga de ventana

$(window).bind("beforeunload", function(){ 


      if (MTG.exitCount<=0) 
      { 

          //do your thing, save etc 
      } 
      MTG.exitCount++; 




}); 
0

he encontrado que en lugar de hacer su propia llamada para confirmar(), acaba de hacer even.preventDefault(); dentro del evento beforeunload. Firefox lanza su propio cuadro de diálogo de confirmación. No estoy seguro de si esto es lo correcto/estándar, pero así es como lo están haciendo.

1

He encontrado este problema en Chrome 21, Firefox 14, IE 7-9, Safari 5 (en PC).

Lo siguiente funciona en todos estos navegadores. Si se elimina la función window.onbeforeunload durante el evento, esto evitará la segunda llamada. El truco es restablecer la función window.onbeforeunload si el usuario decide permanecer en la página.

var window_on_before_unload = function(e) { 
    var msg; 
    // Do here what you ever you need to do 
    msg = "Message for user"; 

    // Prevent next "window.onbeforeunload" from re-running this code. 
    // Ensure that if the user decides to stay on the page that 
    // this code is run the next time the user tries to leave the page. 
    window.onbeforeunload = set_on_before_unload; 

    // Prepare message for user 
    if (msg) { 
     if (/irefox\/([4-9]|1\d+)/.test(navigator.userAgent)) 
      alert(msg 
        + '\n\nThe next dialog will allow you to stay here or continue\nSee Firefox bug #588292'); 

     (e = e || window.event).returnValue = msg; 
     return msg; 
    } 
}; 

// Set window.onbeforeunload to the above handler. 
// @uses window_on_before_unload 
// @param {Event} e 
var set_on_before_unload = function(e) { 
    // Initialize the handler for window.onbeforeunload. 
    window.onbeforeunload = window_on_before_unload; 
} 

// Initialize the handler for window.onbeforeunload. 
set_on_before_unload(); 
-1

Tengo un documento que abre otra ventana emergente con window.open. En la ventana original He registrado (con jQuery) un detector del evento de "descarga" de esta manera:

var popup_window = window.open(...) 
$(popup_window).on('unload', function(event) ... 

he encontré con esta página debido a que el evento se desencadena efectivamente dos veces. Lo que he encontrado es que no es un error, se desencadena dos veces porque se activa una vez para que la página "sobre: ​​en blanco" sea reemplazada por su página y otra para que la página se descargue.

Todo lo que tengo que hacer es filtrar el caso de que Me interesa mediante la consulta del evento original:

function (event) { 
    var original_url = e.originalEvent.originalTarget.URL; 
    if (original_url != 'about:blank') 
    { 
     ... do cool things ... 
    } 
} 

No sé si esto se aplica a la pregunta original, porque es un especial caso de una ventana abriendo otra, pero espero que ayude.

Cuestiones relacionadas