Come posso rilevare se un browser sta bloccando un popup?


130

Di tanto in tanto mi sono imbattuto in una pagina Web che tenta di aprire una nuova finestra (per l'input dell'utente o qualcosa di importante), ma il blocco popup impedisce che ciò accada.

Quali metodi può utilizzare la finestra chiamante per assicurarsi che la nuova finestra sia stata avviata correttamente?

Risposte:


160

Se usi JavaScript per aprire il popup, puoi usare qualcosa del genere:

var newWin = window.open(url);             

if(!newWin || newWin.closed || typeof newWin.closed=='undefined') 
{ 
    //POPUP BLOCKED
}

Ecco una risposta per Chrome: detect-
block

@ajwaka potresti gentilmente chiarire se questa risposta non riesce per Chrome, o c'è un motivo per cui l'altra risposta è migliore per Chrome? Grazie!
Crashalot

@ajwaka almeno oggi questo codice sembra funzionare su Chrome, da qui la domanda.
Crashalot

@Crashalot - Mi stai chiedendo qualcosa a cui ho risposto 6 anni fa - purtroppo non ricordo più la situazione e i browser hanno fatto molta strada in 6 anni.
ajwaka,

40

Ho provato alcuni degli esempi precedenti, ma non sono riuscito a farli funzionare con Chrome. Questo semplice approccio sembra funzionare con Chrome 39, Firefox 34, Safari 5.1.7 e IE 11. Ecco lo snippet di codice dalla nostra libreria JS.

openPopUp: function(urlToOpen) {
    var popup_window=window.open(urlToOpen,"myWindow","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=400, height=400");            
    try {
        popup_window.focus();   
    } catch (e) {
        alert("Pop-up Blocker is enabled! Please add this site to your exception list.");
    }
}

1
@Surendra, per favore, puoi specificare cosa intendi con "non funzionante"? Un errore al momento dell'analisi? Un errore in fase di esecuzione? Il popup si apre ma è contrassegnato come bloccato? Il popup è bloccato ma è contrassegnato come aperto? Non vedo alcun motivo per cui Explorer non fallirebbe, a meno che non sia consentito chiamare focus () su NULL, nel qual caso, un test per NULL prima del tentativo funzionerebbe.
FrancescoMM,

IE restituisce sempre null, anche se il popup ha avuto esito positivo.
Devin Garner,

34

Aggiornamento: i popup esistono da tempi molto antichi. L'idea iniziale era quella di mostrare un altro contenuto senza chiudere la finestra principale. A partire da ora, ci sono altri modi per farlo: JavaScript è in grado di inviare richieste per server, quindi i popup vengono usati raramente. Ma a volte sono ancora utili.

In passato i siti malvagi abusavano molto dei popup. Una cattiva pagina potrebbe aprire tonnellate di finestre popup con annunci. Quindi ora la maggior parte dei browser tenta di bloccare i popup e proteggere l'utente.

La maggior parte dei browser blocca i popup se vengono chiamati all'esterno di gestori di eventi attivati ​​dall'utente come onclick.

Se ci pensi, è un po 'complicato. Se il codice è direttamente in un gestore onclick, allora è facile. Ma cos'è il popup aperto in setTimeout?

Prova questo codice:

 // open after 3 seconds
setTimeout(() => window.open('http://google.com'), 3000);

Il popup si apre in Chrome, ma viene bloccato in Firefox.

... E questo funziona anche in Firefox:

 // open after 1 seconds
setTimeout(() => window.open('http://google.com'), 1000);

La differenza è che Firefox considera accettabile un timeout di 2000ms o meno, ma dopo ciò - rimuove la "fiducia", supponendo che ora sia "al di fuori dell'azione dell'utente". Quindi il primo è bloccato e il secondo no.


Risposta originale che era attuale 2012:

Questa soluzione per il controllo dei blocchi popup è stata testata in FF (v11), Safari (v6), Chrome (v23.0.127.95) e IE (v7 e v9). Aggiorna la funzione displayError per gestire il messaggio di errore come ritieni opportuno.

var popupBlockerChecker = {
    check: function(popup_window){
        var scope = this;
        if (popup_window) {
            if(/chrome/.test(navigator.userAgent.toLowerCase())){
                setTimeout(function () {
                    scope.is_popup_blocked(scope, popup_window);
                },200);
            }else{
                popup_window.onload = function () {
                    scope.is_popup_blocked(scope, popup_window);
                };
            }
        } else {
            scope.displayError();
        }
    },
    is_popup_blocked: function(scope, popup_window){
        if ((popup_window.innerHeight > 0)==false){ 
            scope.displayError();
        }
    },
    displayError: function(){
       alert("Popup Blocker is enabled! Please add this site to your exception list.");
    }
};

Uso:

var popup = window.open("http://www.google.ca", '_blank');
popupBlockerChecker.check(popup);

Spero che questo ti aiuti! :)


20
Penso che tu abbia bisogno di più sottolineature
Jacob Stamm il

In Firefox, questo visualizza la pagina vuota e non puoi nemmeno vedere il messaggio di blocco popup nella pagina di apertura. Come chiudere la pagina vuota?
user460114

Nota che se l'URL popup è un file scaricabile (che ha Content-Disposition: attachment;nell'intestazione della risposta), il popup si chiuderà immediatamente, quindi il setTimeoutcodice fallirà e il browser si lamenterà che "Blocco popup è abilitato!". Per Chrome, raccomando la soluzione di DanielB e funziona alla grande.
Wonsuc,

1
@wonsuc quando si apre un collegamento con Content-Disposition: attachment;un'intestazione non è necessario aprirlo in un popup. Crea semplicemente un collegamento diretto alla risorsa che desideri scaricare e il comportamento nativo del browser ti consentirà di scaricare senza reindirizzarti lontano dalla pagina corrente.
Kevin B,

@KevinB Devo dire che sono in una situazione specifica. Devo scaricare più file che generano file PDF da HTML. E se il contenuto HTML è di grandi dimensioni, a volte ci vogliono diversi secondi e se lo uso window.location, se il primo file impiega troppo tempo per essere generato, verrà ignorato all'avvio della seconda richiesta. Questo è il motivo per cui devo usare window.open, dal momento che window.locationnon mi fa mai sapere quando finisce la risposta.
venerdì

12

Una "soluzione" che funzionerà sempre indipendentemente dalla società o dalla versione del browser è semplicemente quella di mettere un messaggio di avviso sullo schermo, da qualche parte vicino al controllo che creerà un pop-up, che avverte educatamente l'utente che l'azione richiede un pop- e abilitarli per il sito.

So che non è lussuoso o altro, ma non può essere più semplice e richiede solo circa 5 minuti di test, quindi puoi passare ad altri incubi.

Una volta che l'utente ha autorizzato i popup per il tuo sito, sarebbe anche premuroso se non esagerare con i popup. L'ultima cosa che vuoi fare è infastidire i tuoi visitatori.


1
Sfortunatamente, a volte tutte le altre soluzioni in questa domanda non sono accettabili - solo questa. Perché? Perché tutti provano a visualizzare un popup, non solo a rilevare se i popup sono abilitati. E se volessi farlo in silenzio?
Sagi Mann,

Qualcosa da ricordare anche qui è che un utente non può sempre solo abilitare i popup per il tuo sito. Nelle versioni precedenti di Safari, ad esempio, un utente può solo abilitare o disabilitare completamente il blocco popup, senza la whitelisting disponibile.
Jeremy,

1

Ho combinato le soluzioni di @Kevin B e @ DanielB.
Questo è molto più semplice.

var isPopupBlockerActivated = function(popupWindow) {
    if (popupWindow) {
        if (/chrome/.test(navigator.userAgent.toLowerCase())) {
            try {
                popupWindow.focus();
            } catch (e) {
                return true;
            }
        } else {
            popupWindow.onload = function() {
                return (popupWindow.innerHeight > 0) === false;
            };
        }
    } else {
        return true;
    }
    return false;
};

Uso:

var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}

1
isPopupBlockerActivated la funzione non ritorna mai attiva return (popupWindow.innerHeight > 0) === false;. La tua funzione restituisce false quando il tuo browser non è Chrome. Perché onload è un processo asincrono. La tua funzione restituisce false e quindi viene caricata onload ma il suo risultato non ritorna mai.
Onur Gazioğlu

0

Ho provato molte soluzioni, ma l'unica che ho potuto escogitare e che ha funzionato anche con uBlock Origin è stata utilizzando un timeout per verificare lo stato chiuso del popup.

function popup (url, width, height) {
    const left = (window.screen.width / 2) - (width / 2)
    const top = (window.screen.height / 2) - (height / 2)
    let opener = window.open(url, '', `menubar=no, toolbar=no, status=no, resizable=yes, scrollbars=yes, width=${width},height=${height},top=${top},left=${left}`)

    window.setTimeout(() => {
        if (!opener || opener.closed || typeof opener.closed === 'undefined') {
            console.log('Not allowed...') // Do something here.
        }
    }, 1000)
}

Ovviamente questo è un trucco; come tutte le soluzioni a questo problema.

Devi impostare abbastanza tempo nel tuo setTimeout per tenere conto dell'apertura iniziale e della chiusura, quindi non sarà mai completamente accurato. Sarà una posizione di tentativi ed errori.

Aggiungi questo al tuo elenco di tentativi.


0

Un approccio semplice se possiedi anche il codice figlio sarebbe quello di creare una semplice variabile nel suo html come di seguito:

    <script>
        var magicNumber = 49;
    </script>

E poi controlla la sua esistenza dal genitore qualcosa di simile al seguente:

    // Create the window with login URL.
    let openedWindow = window.open(URL_HERE);

    // Check this magic number after some time, if it exists then your window exists
    setTimeout(() => {
        if (openedWindow["magicNumber"] !== 32) {
            console.error("Window open was blocked");
        }
    }, 1500);

Attendiamo un po 'di tempo per assicurarci che la pagina Web sia stata caricata e verificarne l'esistenza. Ovviamente, se la finestra non si caricasse dopo 1500ms, la variabile sarebbe comunque undefined.


-1

Utilizzando l'evento onbeforeunload possiamo verificare come segue

    function popup()
    {
        var chk=false;
        var win1=window.open();
        win1.onbeforeunload=()=>{
            var win2=window.open();
            win2.onbeforeunload=()=>{
                chk=true;
            };
        win2.close();
        };
        win1.close();
        return chk;
    }

aprirà 2 finestre nere sullo sfondo

la funzione restituisce un valore booleano.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.