Detect blocked popup in Chrome

2019-01-02 14:44发布

I am aware of javascript techniques to detect whether a popup is blocked in other browsers (as described in the answer to this question). Here's the basic test:

var newWin = window.open(url);

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

But this does not work in Chrome. The "POPUP BLOCKED" section is never reached when the popup is blocked.

Of course, the test is working to an extent since Chrome doesn't actually block the popup, but opens it in a tiny minimized window at the lower right corner which lists "blocked" popups.

What I would like to do is be able to tell if the popup was blocked by Chrome's popup blocker. I try to avoid browser sniffing in favor of feature detection. Is there a way to do this without browser sniffing?

Edit: I have now tried making use of newWin.outerHeight, newWin.left, and other similar properties to accomplish this. Google Chrome returns all position and height values as 0 when the popup is blocked.

Unfortunately, it also returns the same values even if the popup is actually opened for an unknown amount of time. After some magical period (a couple of seconds in my testing), the location and size information is returned as the correct values. In other words, I'm still no closer to figuring this out. Any help would be appreciated.

16条回答
听够珍惜
2楼-- · 2019-01-02 15:02

Just one improvement to InvisibleBacon's snipet (tested in IE9, Safari 5, Chrome 9 and FF 3.6):

var myPopup = window.open("popupcheck.htm", "", "directories=no,height=150,width=150,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=0,location=no");
if (!myPopup)
    alert("failed for most browsers");
else {
    myPopup.onload = function() {
        setTimeout(function() {
            if (myPopup.screenX === 0) {
                alert("failed for chrome");
            } else {
                // close the test window if popups are allowed.
                myPopup.close();  
            }
        }, 0);
    };
}
查看更多
听够珍惜
3楼-- · 2019-01-02 15:10

This worked for me:

    cope.PopupTest.params = 'height=1,width=1,left=-100,top=-100,location=no,toolbar=no,menubar=no,scrollbars=no,resizable=no,directories=no,status=no';
    cope.PopupTest.testWindow = window.open("popupTest.htm", "popupTest", cope.PopupTest.params);

    if( !cope.PopupTest.testWindow
        || cope.PopupTest.testWindow.closed
        || (typeof cope.PopupTest.testWindow.closed=='undefined')
        || cope.PopupTest.testWindow.outerHeight == 0
        || cope.PopupTest.testWindow.outerWidth == 0
        ) {
        // pop-ups ARE blocked
        document.location.href = 'popupsBlocked.htm';
    }
    else {
        // pop-ups are NOT blocked
        cope.PopupTest.testWindow.close();
    }

The outerHeight and outerWidth are for chrome because the 'about:blank' trick from above doesn't work in chrome anymore.

查看更多
路过你的时光
4楼-- · 2019-01-02 15:11

Here's a version that is currently working in Chrome. Just a small alteration away from Rich's solution, though I added in a wrapper that handles the timing too.

function checkPopupBlocked(poppedWindow) {
 setTimeout(function(){doCheckPopupBlocked(poppedWindow);}, 5000);
}

function doCheckPopupBlocked(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.outerWidth == 0) {
            // This is usually Chrome's doing. The outerWidth (and most other size/location info)
         // will be left at 0, EVEN THOUGH the contents of the popup will exist (including the
         // test function we check for next). The outerWidth starts as 0, so a sufficient delay
         // after attempting to pop is needed.
            result = true;
        }
        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);
        //}
    }

    if(result)
     alert("The popup was blocked. You must allow popups to use this site.");
}

To use it just do this:

var popup=window.open('location',etc...);
checkPopupBlocked(popup);

If the popup get's blocked, the alert message will display after the 5 second grace period (you can adjust that, but 5 seconds should be quite safe).

查看更多
其实,你不懂
5楼-- · 2019-01-02 15:14

As far as I can tell (from what I've tested) Chrome returns a window object with location of 'about:blank'. So, the following should work for all browsers:

var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined' || newWin.location=='about:blank')
{
    //POPUP BLOCKED
}
查看更多
登录 后发表回答