Nun, die "magische Zeit", von der Sie sprechen, ist wahrscheinlich, wenn das DOM des Popups geladen wurde. Oder es kann sein, dass alles (Bilder, Außenborder-CSS usw.) geladen wurde. Sie können dies einfach testen, indem Sie dem Popup eine sehr große Grafik hinzufügen (löschen Sie zuerst Ihren Cache!). Wenn Sie ein Javascript-Framework wie jQuery (oder ähnliches) verwenden, können Sie mit dem Ereignis ready () (oder ähnlichem) warten, bis das DOM geladen ist, bevor Sie den Fensterversatz überprüfen. Die Gefahr besteht darin, dass die Safari-Erkennung auf widersprüchliche Weise funktioniert: Das DOM des Popups ist in Safari niemals bereit (), da es Ihnen ein gültiges Handle für das Fenster gibt, das Sie öffnen möchten - unabhängig davon, ob es tatsächlich geöffnet wird oder nicht nicht. (Tatsächlich glaube ich, dass Ihr Popup-Testcode oben für Safari nicht funktioniert.)
Ich denke, das Beste, was Sie tun können, ist, Ihren Test in ein setTimeout () zu packen und dem Popup 3-5 Sekunden Zeit zu geben, um das Laden abzuschließen, bevor Sie den Test ausführen. Es ist nicht perfekt, aber es sollte mindestens 95% der Zeit funktionieren.
Hier ist der Code, den ich für die browserübergreifende Erkennung ohne den Chrome-Teil verwende.
function _hasPopupBlocker(poppedWindow) {
var result = false;
try {
if (typeof poppedWindow == 'undefined') {
// Safari with popup blocker... leaves the popup window handle undefined
result = true;
}
else if (poppedWindow && poppedWindow.closed) {
// This happens if the user opens and closes the client window...
// Confusing because the handle is still available, but it's in a "closed" state.
// We're not saying that the window is not being blocked, we're just saying
// that the window has been closed before the test could be run.
result = false;
}
else if (poppedWindow && poppedWindow.test) {
// This is the actual test. The client window should be fine.
result = false;
}
else {
// Else we'll assume the window is not OK
result = true;
}
} catch (err) {
//if (console) {
// console.warn("Could not access popup window", err);
//}
}
return result;
}
Ich führe diesen Test vom übergeordneten Element aus aus und verpacke ihn in ein setTimeout (), sodass das untergeordnete Fenster 3-5 Sekunden zum Laden benötigt. Im untergeordneten Fenster müssen Sie eine Testfunktion hinzufügen:
Funktionstest() {}
Der Popup-Blocker-Detektor prüft, ob die Funktion "Test" als Mitglied des untergeordneten Fensters vorhanden ist.
HINZUGEFÜGT 15. JUNI 2015:
Ich denke, die moderne Art, damit umzugehen, wäre die Verwendung von window.postMessage (), damit das Kind das Elternteil benachrichtigt, dass das Fenster geladen wurde. Der Ansatz ist ähnlich (Kind teilt Eltern mit, dass es geladen ist), aber die Kommunikationsmittel haben sich verbessert. Ich konnte diese domänenübergreifende Funktion vom Kind aus ausführen:
$(window).load(function() {
this.opener.postMessage({'loaded': true}, "*");
this.close();
});
Der Elternteil hört auf diese Nachricht mit:
$(window).on('message', function(event) {
alert(event.originalEvent.data.loaded)
});
Hoffe das hilft.