2008-10-01 12 views
20

Ich möchte überprüfen, ob der aktuelle Browser das onbeforeunload-Ereignis unterstützt. Der gemeinsame Javascript Weg, dies zu tun scheint nicht zu funktionieren:onbeforeunload Unterstützung Erkennung

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

Eigentlich ist es nur überprüft, ob einige Handler auf das Ereignis angehängt wurden. Gibt es eine Möglichkeit zu erkennen, ob onbeforeunload unterstützt wird, ohne den jeweiligen Browsernamen zu erkennen?

Antwort

27

Ich schrieb vor einiger Zeit über eine mehr oder weniger reliable inference for detecting event support in modernen Browsern. Sie können auf einer Demo-Seite sehen, dass "beforeunload" in mindestens Safari 4+, FF3.x + und IE unterstützt wird.

Bearbeiten: Diese Technik wird jetzt in jQuery, Prototype verwendet.js, Modernizr und wahrscheinlich andere Skripte und Bibliotheken.

+1

funktioniert nahtlos danke für die gemeinsame Nutzung – jansokoly

+1

Ist die Seite, die oben verlinkt ist? Funktioniert nicht für mich, aber ich fand eine [Cache-Version] (http://webcache.googleusercontent.com/search?q=cache:http://perfectionkills.com/detecting-event-support-without-browser-sniffing /). – regularmike

+1

Warnung: Ich habe einen Kommentar auf [@ kangax's page] (http://perfectionkills.com/detecting-event-support-without-browser-sniffing/#comment-468226) geschrieben, speziell darüber, dass 'onbeforeunload' auf Mobilgeräten erkannt wird Safari obwohl es [tatsächlich nicht zuverlässig funktioniert] (http://stackoverflow.com/questions/3239834/window-onbeforeunload-not-working-on-the-ipad). –

-4

Es wäre wahrscheinlich besser, nur von Hand, um herauszufinden, welchen Browser sie unterstützt und dann bedingt haben mehr wie:

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

... etc.

Die $.browser.msie ist jQuery-Syntax, die meisten Frameworks haben ähnliche integrierte Funktionen, da sie sie intern so oft verwenden. Wenn Sie kein Framework verwenden, würde ich vorschlagen, dass Sie sich nur die Implementierung dieser Funktionen von jQuery ansehen.

0

anderen Ansatz, erhalten die typeof

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

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

scheint nicht zu funktionieren – jansokoly

+1

welchen Browser testen Sie dies gegen? – curtisk

+0

alle von ihnen, IE, Opera, Safari, Firefox Ihr Code funktioniert nicht in jedem Browser if (typeof window.onbeforeunload! = 'Undefined') ist in der Nähe, aber nicht in FF – jansokoly

2
alert('onbeforeunload' in window); 

Alerts 'true', wenn onbeforeunload ist eine Eigenschaft von window (auch wenn es null ist).

Dies sollte das gleiche tun:

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

Schließlich:

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

Wieder typeof window.onbeforeunload erscheint 'Objekt' zu sein, auch wenn es zur Zeit den Wert null hat, so dass dies funktioniert.

+0

fast in IE, Opera funktioniert gut und Safari, aber FF gibt mir falsch, was nicht korrekt zu sein scheint – jansokoly

+0

Entschuldigung, ich dachte, es funktionierte zuverlässig, weil ich nicht erkannte, dass Firefox onforefunload unterstützt. –

+0

Firefox unterstützt diese Art der Inferenz nicht, aber ermöglicht es, "beforeunload" zu erkennen, indem das entsprechende Attribut für ein Element gesetzt wird. var el = document.createElement ('div'); el.setAttribute ('onbeforeunload', ''); typeof el.onbeforeunload; // "function" – daniellmb

2

cruster,

Die "beforeunload" ist nicht in der DOM-Events-Spezifikation definiert, ist dies eine IE-spezifische Funktion. Ich denke, es wurde erstellt, um zu ermöglichen, dass die Ausführung vor dem Standard-Entlade-Ereignis ausgelöst wird. In anderen als IE-Browsern können Sie den "listen" -Ereignis-Listener für die Erfassungsphase verwenden, um Code vor beispielsweise einem Inline-Body-on-load-Ereignis auszuführen.

Auch DOM keine Schnittstellen bieten ihre Unterstützung für ein bestimmtes Ereignis zu testen, können Sie nur Test für die Unterstützung einer Gruppenveranstaltungen (Mouseevents, Mutation etc.)

der Zwischenzeit können Sie auch beziehen DOM-Events Spezifikation http://www.w3.org/TR/DOM-Level-3-Events/events.html (leider nicht in IE unterstützt)

Hoffnung hilft diese Informationen einige auch

+1

ist. Danke, Kumpel, aber das ist nur Theorie - siehe andere Antworten auf diese Fragen und Sie werden fast perfekte Lösungen finden. Es ist mir also egal, ob DOM eine Schnittstelle anbietet oder nicht. In der Realität gibt es zuverlässige Wege, um es zu überprüfen, das ist wichtig. Ach, übrigens, nur Opera fehlt die Unterstützung. – jansokoly

0

onbeforeunload von FF unterstützt wird, so für die Browser-Prüfung wird nicht helfen.

6

Ich weiß, dass ich ein bisschen spät dran bin, aber ich beschäftige mich jetzt damit, und ich dachte, dass etwas wie das Folgende einfacher und zuverlässiger wäre. Dies ist jQuery-spezifisch, sollte jedoch mit jedem System funktionieren, mit dem Sie Ereignisse binden und lösen können.

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

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

Dies sollte die unload Ereignis, wenn die beforeunload Ereignis ausgelöst wird entbinden. Andernfalls wird einfach das Entladen ausgelöst.

7

Leider funktioniert kangax's answer nicht für Safari on iOS. In meinen Tests beforeunload wurde in jedem Browser unterstützt ich genau, außer Safari auf IOS versucht :-(

Stattdessen schlage ich einen anderen Ansatz.

Die Idee ist einfach auf der ersten Seite besucht, wissen wir nicht weiß eigentlich noch, wenn beforeunload unterstützt wird. Aber an dieser ersten Seite, wir gründeten einen beide unload und einen beforeunload Handler. wenn das beforeunload Handler Feuer, wir Flag gesetzt sagen, dass beforeunload unterstützt wird (tatsächlich beforeunloadSupported = "yes"). wenn Der unload Handler wird ausgelöst, wenn das Flag nicht gesetzt wurde, setzen wir flag, dass beforeunload ist nicht unterstützt.

Im Folgenden verwenden wir localStorage (unterstützt in allen Browsern, die ich interessiere über - siehe http://caniuse.com/namevalue-storage), um das Flag zu erhalten/setzen. Wir hätten genauso gut einen Cookie verwenden können, aber ich habe localStorage gewählt, weil dort kein Grund ist, diese Informationen bei jeder Anfrage an den Webserver zu senden. Wir brauchen nur eine Flagge, die Seiten neu lädt überlebt. Sobald wir es einmal erkannt haben, bleibt es für immer erkannt.

Mit diesem können Sie jetzt anrufen isBeforeunloadSupported() und es wird Ihnen sagen.

(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); 

Hier ist ein voller jsfiddle mit Beispielverwendung.

Beachten Sie, dass es nur beim zweiten oder nachfolgenden Laden Ihrer Website erkannt wurde. Wenn es wichtig ist, dass es auch auf der allerersten Seite funktioniert, können Sie iframe auf dieser Seite mit einem src-Attribut laden, das auf eine Seite in derselben Domäne mit der Erkennung hier zeigt, stellen Sie sicher, dass es geladen und dann entfernt wurde es. Das sollte sicherstellen, dass die Erkennung erfolgt ist, so funktioniert isBeforeunloadSupported() sogar auf der ersten Seite. Aber ich brauchte das nicht, also habe ich das nicht in meine Demo aufgenommen.

-1

Ich sehe, dass dies ein sehr alter Thread, aber die akzeptierte Antwort erkennt falsch Unterstützung für Safari auf iOS, was dazu führte, mir andere Strategien zu untersuchen:

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

Der zweite Teil des if-Check ist notwendig für Safari unter iOS, bei dem die Eigenschaft auf null gesetzt ist.

Getestet in Chrome 37, IE11, Firefox 32 und Safari für iOS 7.1

+0

'onbeforeunload' wird standardmäßig immer auf null gesetzt. Wenn Sie eine OnbeforeUnload-Funktion einstellen, ist dies immer eine Funktion. Das bedeutet nicht, dass es ausgelöst wird. Ich tue nicht was du getestet hast, aber das wird nicht funktionieren. Der einzige Weg hier ist die Erkennung von iOS-Geräten oder die Methode von Peter V. Mørch. – hexalys