Ebbene, il "momento magico" di cui parli è probabilmente quando il DOM del popup è stato caricato. Oppure potrebbe essere quando tutto (immagini, CSS fuoribordo, ecc.) È stato caricato. Puoi testarlo facilmente aggiungendo un'immagine molto grande al popup (svuota prima la cache!). Se stavi usando un framework Javascript come jQuery (o qualcosa di simile), potresti usare l'evento ready () (o qualcosa di simile) per attendere il caricamento del DOM prima di controllare l'offset della finestra. Il pericolo in questo è che il rilevamento di Safari funzioni in modo conflittuale: il DOM del popup non sarà mai pronto () in Safari perché ti darà un handle valido per la finestra che stai cercando di aprire, indipendentemente dal fatto che si apra o non. (infatti, credo che il tuo codice di test popup sopra non funzionerà per Safari.)
Penso che la cosa migliore che puoi fare sia racchiudere il tuo test in un setTimeout () e dare al popup 3-5 secondi per completare il caricamento prima di eseguire il test. Non è perfetto, ma dovrebbe funzionare almeno il 95% delle volte.
Ecco il codice che utilizzo per il rilevamento cross-browser, senza la parte Chrome.
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;
}
Quello che faccio è eseguire questo test dal genitore e avvolgerlo in un setTimeout (), dando alla finestra figlio 3-5 secondi per il caricamento. Nella finestra figlio, è necessario aggiungere una funzione di test:
test di funzionalita() {}
Il rilevatore di blocco dei popup verifica se la funzione "test" esiste come membro della finestra figlia.
AGGIUNTO 15 GIUGNO 2015:
Penso che il modo moderno per gestirlo sarebbe usare window.postMessage () per fare in modo che il bambino notifichi al genitore che la finestra è stata caricata. L'approccio è simile (il bambino dice al genitore che è caricato), ma i mezzi di comunicazione sono migliorati. Sono stato in grado di eseguire questo cross-domain dal bambino:
$(window).load(function() {
this.opener.postMessage({'loaded': true}, "*");
this.close();
});
Il genitore ascolta questo messaggio usando:
$(window).on('message', function(event) {
alert(event.originalEvent.data.loaded)
});
Spero che questo ti aiuti.