2008-10-01 22 views
20

Me gustaría comprobar si el navegador actual admite el evento onbeforeunload. No parece que la manera Javascript común de hacer que esto funcione:onbeforeunload support detection

if (window.onbeforeunload) { 
    alert('yes'); 
} 
else { 
    alert('no'); 
} 

En realidad, sólo se comprueba si algún controlador se ha adjuntado al evento. ¿Hay alguna forma de detectar si onbeforeunload es compatible sin detectar el nombre del navegador en particular?

Respuesta

27

Escribí sobre un más o menos reliable inference for detecting event support en los navegadores modernos hace algún tiempo. Puede ver en una página de demostración que "beforeunload" es compatible al menos con Safari 4+, FF3.x + e IE.

Editar: Esta técnica ahora se utiliza en jQuery, Prototype.js, Modernizr, y probablemente otros scripts y bibliotecas.

+1

funciona a la perfección gracias por compartir – jansokoly

+1

¿El sitio está vinculado a arriba? No funciona, pero encontré una [versión en caché] (http://webcache.googleusercontent.com/search?q=cache:http://perfectionkills.com/detecting-event-support-without-browser-sniffing /). – regularmike

+1

Advertencia: escribí un comentario en la página [@ kangax] (http://perfectionkills.com/detecting-event-support-without-browser-sniffing/#comment-468226) específicamente sobre la detección de 'onbeforeunload' como compatible con Mobile Safari a pesar de que [en realidad no funciona de manera confiable] (http://stackoverflow.com/questions/3239834/window-onbeforeunload-not-working-on-the-ipad). –

-4

Probablemente sería mejor encontrar simplemente a mano, que soportan los navegadores y luego tener su condicional más como:

if($.browser.msie) { 
    alert('no'); 
} 

... etc.

La $.browser.msie es la sintaxis de jQuery, la mayoría de las estructuras tienen funciones integradas similares, ya que las usan tanto internamente. Si no está utilizando un marco, entonces le sugiero que eche un vistazo a la implementación de jQuery de esas funciones.

0

enfoque diferente, conseguir el typeof

if(typeof window.onbeforeunload == 'function') 

{ 
alert("hello functionality!"); 
} 
+0

parece que tampoco funciona – jansokoly

+1

¿con qué navegador está probando esto? – curtisk

+0

todos ellos, IE, Opera, Safari, Firefox su código no funciona en ningún navegador if (typeof window.onbeforeunload! = 'Undefined') está cerca, pero falla en FF – jansokoly

2
alert('onbeforeunload' in window); 

Alertas 'verdadero' si onbeforeunload es una propiedad de window (incluso si es nulo).

Esto debería hacer lo mismo:

var supportsOnbeforeunload = false; 
for (var prop in window) { 
    if (prop === 'onbeforeunload') { 
    supportsOnbeforeunload = true; 
    break; 
    } 
} 
alert(supportsOnbeforeunload); 

Por último:

alert(typeof window.onbeforeunload != 'undefined'); 

Una vez más, typeof window.onbeforeunload que parece ser 'objeto', incluso si actualmente tiene el valor null, por lo que este funciona.

+0

casi funciona bien en IE, Opera y Safari, pero FF me da falso, lo que no parece correcto – jansokoly

+0

Lo siento, pensé que estaba funcionando de manera confiable porque no me di cuenta de que Firefox era compatible antes de la descarga. –

+0

Firefox no admite ese tipo de inferencia, pero permite detectar "beforeunload" estableciendo el atributo correspondiente en un elemento. var el = document.createElement ('div'); el.setAttribute ('onbeforeunload', ''); typeof el.onbeforeunload; // "función" – daniellmb

2

cruster,

El "beforeunload" no está definido en la especificación DOM-Events, esta es una característica IE-específico. Creo que fue creado para permitir que la ejecución se active antes del evento estándar de "descarga". En otros navegadores IE, puede utilizar el detector de eventos de "descarga" de la fase de captura obteniendo así el código ejecutado antes, por ejemplo, un evento onunload de cuerpo en línea.

Además, DOM no ofrece ninguna interfaz para poner a prueba su apoyo a un evento específico, puede Mientras tanto también puede referirse sólo de prueba para el apoyo de un grupo de eventos (MouseEvents, etc.) MutationEvents

con la especificación DOM-Events http://www.w3.org/TR/DOM-Level-3-Events/events.html (por desgracia no es compatible con IE)

Esperamos que esta información ayude a algunos

+1

Gracias amigo, pero esto es solo teoría, vea otras respuestas a estas preguntas y encontrará soluciones casi perfectas. Entonces, realmente no me importa si DOM ofrece alguna interfaz o no. En realidad, hay maneras confiables de cómo verificarlo, eso es importante. Oh, por cierto, solo a Opera le falta el soporte. – jansokoly

0

onbeforeunload también es apoyado por FF, lo que las pruebas para el navegador no ayudará.

6

Me doy cuenta de que estoy un poco tarde en esto, pero estoy lidiando con esto ahora, y estaba pensando que algo más como el siguiente sería más fácil y más confiable. Esto es específico de jQuery, pero debería funcionar con cualquier sistema que le permita vincular y desvincular eventos.

$(window).bind('unload', function(){ 
    alert('unload event'); 
}); 

window.onbeforeunload = function(){ 
    $(window).unbind('unload'); 
    return 'beforeunload event'; 
} 

Esto debe desenlazar el caso unload si los beforeunload desencadena el evento. De lo contrario, simplemente disparará la descarga.

7

Desafortunadamente kangax's answer no funciona para Safari on iOS. En mis pruebas beforeunload fue apoyado en todos los navegadores Probé exactamente excepto Safari en iOS :-(

lugar Sugiero un enfoque diferente:.

La idea es simple en la primera visita la página, no lo hacemos en realidad sabemos todavía si se admite beforeunload. Pero en esa primera página, hemos creado tanto un unload y una beforeunload manejador. Si los beforeunload incendios de controlador, que establece un indicador diciendo que beforeunload se apoya (en realidad beforeunloadSupported = "yes"). Cuando el controlador unload se activa, si no se ha establecido el indicador, configuramos el marca que beforeunload es no compatible.

A continuación utilizaremos localStorage (compatible con todos los navegadores que me importan - vea http://caniuse.com/namevalue-storage) para obtener/configurar la bandera. Nosotros podríamos haber usado una cookie, pero elegí localStorage porque no es razón para enviar esta información al servidor web en cada solicitud. Nosotros solo necesitamos una bandera que sobreviva a las recargas de página. Una vez que lo hayamos detectado una vez, se mantendrá detectado por .

Con esto, ahora puede llamar al isBeforeunloadSupported() y le avisará.

(function($) { 
    var field = 'beforeunloadSupported'; 
    if (window.localStorage && 
     window.localStorage.getItem && 
     window.localStorage.setItem && 
     ! window.localStorage.getItem(field)) { 
     $(window).on('beforeunload', function() { 
      window.localStorage.setItem(field, 'yes'); 
     }); 
     $(window).on('unload', function() { 
      // If unload fires, and beforeunload hasn't set the field, 
      // then beforeunload didn't fire and is therefore not 
      // supported (cough * iPad * cough) 
      if (! window.localStorage.getItem(field)) { 
       window.localStorage.setItem(field, 'no'); 
      } 
     }); 
    } 
    window.isBeforeunloadSupported = function() { 
     if (window.localStorage && 
      window.localStorage.getItem && 
      window.localStorage.getItem(field) && 
      window.localStorage.getItem(field) == "yes") { 
      return true; 
     } else { 
      return false; 
     } 
    } 
})(jQuery); 

Aquí hay un completo jsfiddle con uso de ejemplo.

Tenga en cuenta que solo se detectará en la segunda página o en las siguientes cargas de página en su sitio. Si también es importante tenerlo trabajando en la primera página, puede cargar un iframe en esa página con un atributo src apuntando a una página en el mismo dominio con la detección aquí, asegúrese de que se haya cargado y luego eliminar eso. Eso debería garantizar que la detección se haya realizado para que isBeforeunloadSupported() funcione incluso en la primera página. Pero no lo necesitaba, así que no lo puse en mi demo.

-1

veo que este es un hilo muy antiguo, pero la respuesta aceptada detecta incorrectamente soporte para Safari en iOS, lo que me hizo investigar otras estrategias:

if ('onbeforeunload' in window && typeof window['onbeforeunload'] === 'function') { 
    // onbeforeunload is supported 
} else { 
    // maybe bind to unload as a last resort 
} 

La segunda parte de la comprobación de si-es necesario para Safari en iOS, que tiene la propiedad configurada en null.

Probado en Chrome 37, IE11, Firefox 32 y Safari para iOS 7.1

+0

'onbeforeunload' siempre se establece en nulo de forma predeterminada. Si configura una función 'onbeforeunload' siempre será una función. Eso no quiere decir que se va a activar. No hice lo que probaste, pero eso no funcionará. La única manera aquí es la detección de dispositivos iOS o el método de Peter V. Mørch. – hexalys