ブラウザがポップアップをブロックしているかどうかをどのように検出できますか?


130

ときどき、新しいウィンドウを(ユーザー入力または重要な何かのために)ポップオープンしようとするWebページに出くわしましたが、ポップアップブロッカーがこれを防止しています。

新しいウィンドウが正しく起動することを確認するために、呼び出しウィンドウはどのようなメソッドを使用できますか?

回答:


160

JavaScriptを使用してポップアップを開く場合は、次のようなものを使用できます。

var newWin = window.open(url);             

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

ここでは、クロムのための答えです:ブロックされた-ポップアップ・イン・クロムを検出
ajwaka

@ajwakaこの回答がクロームで失敗するかどうかを親切に明確にしていただけますか、それとも他の回答がクロームに適している理由がありますか?ありがとう!
Crashalot

@ajwaka少なくとも今日、このコードはChromeで機能するようです。そのため、質問です。
Crashalot

@Crashalot-私が6年前にこれに回答したことについて私に尋ねています-悲しいことに状況を思い出せず、ブラウザは6年で長い道のりを歩んできました。
ajwaka

40

上記の例をいくつか試しましたが、Chromeで動作させることができませんでした。このシンプルなアプローチは、Chrome 39、Firefox 34、Safari 5.1.7、IE 11で機能するようです。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お願い、「機能しない」とはどういう意味ですか?解析時のエラー?実行時のエラー?ポップアップは開きますが、ブロック済みとマークされていますか?ポップアップはブロックされていますが、開いているとマークされていますか?エクスプローラーがこれに失敗する理由はわかりませんが、NULLでfocus()を呼び出すことが許可されていない場合は、試行前にNULLをテストするだけで十分です。
FrancescoMM

ポップアップが成功した場合でも、IEは常にnullを返します。
Devin Garner、

34

更新:ポップアップは本当に古代から存在します。最初のアイデアは、メインウィンドウを閉じずに別のコンテンツを表示することでした。現在、これを行う方法は他にもあります。JavaScriptはサーバーへのリクエストを送信できるため、ポップアップはほとんど使用されません。しかし、時にはそれでも便利です。

過去の邪悪なサイトでは、ポップアップを悪用していました。悪いページは、たくさんのポップアップウィンドウを広告で開く可能性があります。したがって、ほとんどのブラウザはポップアップをブロックしてユーザーを保護しようとします。

ほとんどのブラウザーは、onclickなどのユーザートリガーイベントハンドラーの外部で呼び出されると、ポップアップをブロックします。

考えてみると、少しトリッキーです。コードが直接onclickハンドラーにある場合、それは簡単です。しかし、ポップアップはsetTimeoutで何を開きますか?

このコードを試してください:

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

ポップアップはChromeで開きますが、Firefoxではブロックされます。

…そして、これはFirefoxでも機能します。

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

違いは、Firefoxが2000ミリ秒以下のタイムアウトを処理できることですが、それ以降は「信頼」を取り除き、「ユーザーアクションの範囲外」になったと仮定します。つまり、最初のものはブロックされ、2番目のものはブロックされません。


現在の2012年の元の回答:

このポップアップブロッカーチェックのソリューションは、FF(v11)、Safari(v6)、Chrome(v23.0.127.95)およびIE(v7&v9)でテストされています。必要に応じてエラーメッセージを処理するようにdisplayError関数を更新します。

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

使用法:

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

お役に立てれば!:)


20
もっとアンダースコアが必要だと思います
Jacob Stamm

Firefoxでは、これにより空白のページが表示され、オープナーページにポップアップブロッカーメッセージを表示することもできません。空白のページを閉じる方法は?
user460114

ポップアップURLがダウンロード可能なファイル(Content-Disposition: attachment;応答ヘッダーにある)の場合、ポップアップはすぐに閉じるため、setTimeoutコードは失敗し、ブラウザーは「ポップアップブロッカーが有効になっています!」というメッセージを表示します。Chromeの場合、@ DanielBのソリューションをお勧めします。
wonsuc

1
@wonsuc Content-Disposition: attachment;ヘッダーのあるリンクを開くときに、ポップアップで開く必要はありません。ダウンロードするアセットへの直接リンクを作成するだけで、ブラウザーのネイティブ動作により、現在のページからリダイレクトすることなくダウンロードできます。
ケビンB

@KevinB私は特定の状況にいると言わざるを得ません。HTMLからPDFファイルを生成している複数のファイルをダウンロードする必要があります。また、HTMLコンテンツが大きい場合は、数秒かかることがあります。使用window.locationすると、最初のファイルの生成に時間がかかりすぎる場合、2番目のリクエストが開始されたときに無視されます。これが私がを使用しなければならない理由です。応答がいつ終了するかを通知することは決してないwindow.openからwindow.locationです。
wonsuc

12

ブラウザの会社やバージョンに関係なく常に機能する「解決策」の1つは、ポップアップを作成するコントロールの近くの画面に警告メッセージを表示することです。これにより、アクションにはポップアップが必要であることをユーザーに丁寧に警告しますアップして、サイトでそれらを有効にしてください。

私はそれが派手なことでも何でもないことを知っていますが、それはもっと簡単にすることはできず、約5分のテストを必要とするだけなので、他の悪夢に進むことができます。

ユーザーがサイトのポップアップを許可したら、ポップアップをやりすぎないようにすることも考慮されます。あなたがしたい最後のことはあなたの訪問者を困らせることです。


1
残念ながら、この質問の他のすべての解決策は受け入れられないことがあります-これだけです。どうして?それらはすべてポップアップを表示しようとするからです-ポップアップが有効になっているかどうかを検出するだけではありません。黙ってやりたいのですが?
Sagi Mann

ここで覚えておかなければならないのは、ユーザーがサイトのポップアップを常に有効にできるとは限らないことです。たとえば、古いバージョンのSafariでは、ユーザーはポップアップブロッカーを完全に有効または無効にできるだけで、ホワイトリストは利用できません。
ジェレミー

1

@Kevin Bと@DanielBのソリューションを組み合わせました。
これははるかに簡単です。

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

使用法:

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

1
isPopupBlockerActivated 関数はを返しませんreturn (popupWindow.innerHeight > 0) === false;。ブラウザがChromeでない場合、関数はfalseを返します。onloadは非同期プロセスだからです。関数はfalseを返し、onloadが実行されますが、その結果は返されません。
OnurGazioğlu19年

0

たくさんの解決策を試しましたが、uBlock Originでも機能するのは、タイムアウトを利用してポップアップのクローズ状態を確認することだけでした。

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

明らかにこれはハックです。この問題のすべての解決策と同様に。

最初の開閉を考慮するために、setTimeoutに十分な時間を提供する必要があるため、完全に正確になることはありません。試行錯誤の位置になります。

これを試行リストに追加します。


0

子コードも所有している場合の簡単なアプローチは以下のようにHTMLに単純な変数を作成することです。

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

そして、次のような親からの存在を確認します。

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

ウェブページが読み込まれたことを確認し、その存在を確認するまでしばらく待機します。明らかに、ウィンドウが1500ms後にロードされなかった場合、変数はまだですundefined


-1

onbeforeunloadイベントを使用すると、次のように確認できます

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

バックグラウンドで2つの黒いウィンドウを開きます

関数はブール値を返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.