Wie kann ich feststellen, ob ein Browser ein Popup blockiert?

130

Gelegentlich bin ich auf eine Webseite gestoßen, die versucht, ein neues Fenster zu öffnen (für Benutzereingaben oder etwas Wichtiges), aber der Popup-Blocker verhindert dies.

Mit welchen Methoden kann das aufrufende Fenster sicherstellen, dass das neue Fenster ordnungsgemäß gestartet wird?

Nathan Bedford
quelle

Antworten:

160

Wenn Sie das Popup mit JavaScript öffnen, können Sie Folgendes verwenden:

var newWin = window.open(url);             

if(!newWin || newWin.closed || typeof newWin.closed=='undefined') 
{ 
    //POPUP BLOCKED
}
omar
quelle
Hier ist eine Antwort für Chrom:
Block
@ajwaka Könnten Sie bitte klarstellen, ob diese Antwort für Chrom fehlschlägt, oder gibt es einen Grund, warum die andere Antwort für Chrom besser ist? Vielen Dank!
Crashalot
@ajwaka Zumindest heute scheint dieser Code auf Chrom zu funktionieren, daher die Frage.
Crashalot
@Crashalot - Sie fragen mich nach etwas, das ich vor 6 Jahren beantwortet habe - Ich erinnere mich leider nicht mehr an die Situation und Browser haben in 6 Jahren einen langen Weg zurückgelegt.
Ajwaka
40

Ich habe einige der obigen Beispiele ausprobiert, konnte sie jedoch nicht mit Chrome zum Laufen bringen. Dieser einfache Ansatz scheint mit Chrome 39, Firefox 34, Safari 5.1.7 und IE 11 zu funktionieren. Hier ist der Codeausschnitt aus unserer JS-Bibliothek.

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.");
    }
}
DanielB
quelle
1
@ Surendra bitte, kannst du angeben, was du mit "nicht funktioniert" meinst? Ein Fehler beim Analysieren? Ein Fehler zur Laufzeit? Das Popup wird geöffnet, aber als blockiert markiert. Das Popup ist blockiert, aber als offen markiert? Ich sehe keinen Grund, warum der Explorer dies fehlschlagen würde, es sei denn, der Aufruf von focus () für NULL ist zulässig. In diesem Fall würde ein Test für NULL vor dem Versuch einfach funktionieren.
FrancescoMM
IE gibt immer null zurück, auch wenn das Popup erfolgreich war.
Devin Garner
34

Update: Popups existieren aus sehr alten Zeiten. Die ursprüngliche Idee war, einen anderen Inhalt anzuzeigen, ohne das Hauptfenster zu schließen. Ab sofort gibt es andere Möglichkeiten, dies zu tun: JavaScript kann Serveranforderungen senden, sodass Popups selten verwendet werden. Aber manchmal sind sie immer noch praktisch.

In der Vergangenheit haben böse Websites Popups häufig missbraucht. Eine schlechte Seite könnte Tonnen von Popup-Fenstern mit Anzeigen öffnen. Daher versuchen die meisten Browser jetzt, Popups zu blockieren und den Benutzer zu schützen.

Die meisten Browser blockieren Popups, wenn sie außerhalb von vom Benutzer ausgelösten Ereignishandlern wie onclick aufgerufen werden.

Wenn Sie darüber nachdenken, ist das ein bisschen schwierig. Wenn sich der Code direkt in einem Onclick-Handler befindet, ist das einfach. Aber was öffnet das Popup in setTimeout?

Versuchen Sie diesen Code:

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

Das Popup wird in Chrome geöffnet, in Firefox jedoch blockiert.

… Und das funktioniert auch in Firefox:

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

Der Unterschied besteht darin, dass Firefox behandelt, dass eine Zeitüberschreitung von 2000 ms oder weniger akzeptabel ist. Danach wird jedoch das "Vertrauen" entfernt, vorausgesetzt, es befindet sich jetzt "außerhalb der Benutzeraktion". Der erste ist also blockiert und der zweite nicht.


Ursprüngliche Antwort, die aktuell 2012 war:

Diese Lösung für die Überprüfung von Popupblockern wurde in FF (v11), Safari (v6), Chrome (v23.0.127.95) und IE (v7 & v9) getestet. Aktualisieren Sie die Funktion displayError, um die Fehlermeldung nach Belieben zu behandeln.

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.");
    }
};

Verwendung:

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

Hoffe das hilft! :) :)

Kevin B.
quelle
20
Ich denke, Sie brauchen mehr Unterstriche
Jacob Stamm
In Firefox wird die leere Seite angezeigt, und Sie können nicht einmal die Popupblocker-Meldung auf der Öffnerseite sehen. Wie schließe ich die leere Seite?
user460114
Beachten Sie, dass wenn die Popup-URL eine herunterladbare Datei ist (die sich Content-Disposition: attachment;im Antwortheader befindet), das Popup sofort geschlossen wird, der setTimeoutCode daher fehlschlägt und der Browser sich beschwert, dass "Popup-Blocker aktiviert ist!". Für Chrome empfehle ich die Lösung von @ DanielB und sie funktioniert hervorragend.
Wonsuc
1
@wonsuc Wenn Sie einen Link mit einem Content-Disposition: attachment;Header öffnen, müssen Sie ihn nicht in einem Popup öffnen. Stellen Sie einfach einen direkten Link zu dem Asset her, das Sie herunterladen möchten, und das native Verhalten des Browsers ermöglicht Ihnen das Herunterladen, ohne Sie von der aktuellen Seite wegzuleiten.
Kevin B
@ KevinB Ich muss sagen, dass ich in einer bestimmten Situation bin. Ich muss mehrere Dateien herunterladen, die PDF-Dateien aus HTML generieren. Und wenn der HTML-Inhalt groß ist, dauert es manchmal einige Sekunden, und wenn ich window.locationihn verwende, wird das Generieren der ersten Datei beim Starten der zweiten Anforderung ignoriert. Das ist der Grund, warum ich verwenden muss window.open, da window.locationich nie weiß, wann die Antwort beendet ist.
Wonsuc
12

Eine "Lösung", die unabhängig von der Browser-Firma oder -Version immer funktioniert, besteht darin, einfach eine Warnmeldung auf dem Bildschirm zu platzieren, die sich in der Nähe des Steuerelements befindet und ein Popup erstellt, das den Benutzer höflich warnt, dass für die Aktion ein Popup erforderlich ist. bis und bitte aktivieren Sie sie für die Website.

Ich weiß, es ist nichts Besonderes oder so, aber es kann nicht einfacher werden und erfordert nur etwa 5 Minuten Testzeit, dann können Sie zu anderen Albträumen übergehen.

Sobald der Benutzer Popups für Ihre Site zugelassen hat, ist es auch rücksichtsvoll, wenn Sie die Popups nicht übertreiben. Das Letzte, was Sie tun möchten, ist, Ihre Besucher zu ärgern.

UncaAlby
quelle
1
Leider sind manchmal alle anderen Lösungen in dieser Frage nicht akzeptabel - nur diese. Warum? Weil alle versuchen, ein Popup anzuzeigen - nicht nur zu erkennen, ob Popups aktiviert sind. Was ist, wenn ich es still machen möchte?
Sagi Mann
Beachten Sie auch hier, dass ein Benutzer nicht immer nur Popups für Ihre Site aktivieren kann. In älteren Versionen von Safari kann ein Benutzer beispielsweise den Popup-Blocker nur vollständig aktivieren oder deaktivieren, ohne dass eine Whitelist verfügbar ist.
Jeremy
1

Ich habe die Lösungen von @Kevin B und @ DanielB kombiniert.
Das ist viel einfacher.

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;
};

Verwendung:

var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}
Wonsuc
quelle
1
isPopupBlockerActivated Funktion kehrt nie zurück return (popupWindow.innerHeight > 0) === false;. Ihre Funktion gibt false zurück, wenn Ihr Browser nicht Chrome ist. Weil Onload ein asynchroner Prozess ist. Ihre Funktion gibt false zurück und dann wird onload ausgeführt, aber das Ergebnis wird nie zurückgegeben.
Onur Gazioğlu
0

Ich habe viele Lösungen ausprobiert, aber die einzige Lösung, die ich auch mit uBlock Origin finden konnte, war die Verwendung einer Zeitüberschreitung, um den geschlossenen Status des Popups zu überprüfen.

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)
}

Offensichtlich ist dies ein Hack; wie alle Lösungen für dieses Problem.

Sie müssen in Ihrem setTimeout genügend Zeit bereitstellen, um das anfängliche Öffnen und Schließen zu berücksichtigen, damit es niemals genau wird. Es wird eine Position des Versuchs und Irrtums sein.

Fügen Sie dies Ihrer Liste der Versuche hinzu.

Michael Giovanni Pumo
quelle
0

Ein einfacher Ansatz, wenn Sie auch den untergeordneten Code besitzen , besteht darin, eine einfache Variable in ihrem HTML wie folgt zu erstellen:

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

Und dann überprüfen Sie seine Existenz vom Elternteil etwas Ähnliches wie das Folgende:

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

Wir warten einige Zeit, um sicherzustellen, dass die Webseite geladen wurde, und überprüfen ihre Existenz. Wenn das Fenster nach 1500 ms nicht geladen würde, wäre die Variable natürlich immer noch undefined.

Lalit Umbarkar
quelle
-1

Mit dem Ereignis onbeforeunload können wir Folgendes überprüfen

    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;
    }

Es werden 2 schwarze Fenster im Hintergrund geöffnet

Die Funktion gibt einen booleschen Wert zurück.

Yash Bora
quelle