How can I detect if a browser is blocking a popup?

Detect if a browser is blocking a popup

Occasionally, I've come across a webpage that tries to pop open a new window (for user input, or something important), but the popup blocker prevents this from happening.

What methods can the calling window use to make sure the new window launched properly?

9 Answers

If you use JavaScript to open the popup, you can use something like this:

var newWin = window.open(url);

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

Here's an answer for chrome: detect-blocked-popup-in-chrome

@ ajwaka could you kindly clarify if this answer fails for chrome, or is there a reason the other answer is better for chrome? thanks!

@ ajwaka at least today this code seems to work on chrome, hence the question.

@ Crashalot - You're asking me about something I answered this 6 years ago - I sadly no longer recall the situation and browsers have come a long ways in 6 years.

I tried a number of the examples above, but I could not get them to work with Chrome. This simple approach seems to work with Chrome 39, Firefox 34, Safari 5.1.7, and IE 11. Here is the snippet of code from our JS library.

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

@ Surendra please, can you specify what you mean with "not working"? An error at parse time? An error at runtime? The popup opens but it is marked as blocked? The popup is blocked but it is marked as open? I don't see any reason why explorer would fail this, unless calling focus() on NULL is allowed in which case, a test for NULL before the try would just work.

IE always returns null, even if the popup was successful.

Update: Popups exist from really ancient times. The initial idea was to show another content without closing the main window. As of now, there are other ways to do that: JavaScript is able to send requests for server, so popups are rarely used. But sometimes they are still handy.

In the past evil sites abused popups a lot. A bad page could open tons of popup windows with ads. So now most browsers try to block popups and protect the user.

Most browsers block popups if they are called outside of user-triggered event handlers like onclick.

If you think about it, that’s a bit tricky. If the code is directly in an onclick handler, then that’s easy. But what is the popup opens in setTimeout?

Try this code:

// open after 3 seconds
setTimeout(() => window.open('http_google_com'), 3000);

The popup opens in Chrome, but gets blocked in Firefox.

…And this works in Firefox too:

// open after 1 seconds
setTimeout(() => window.open('http_google_com'), 1000);

The difference is that Firefox treats a timeout of 2000ms or less are acceptable, but after it – removes the “trust”, assuming that now it’s “outside of the user action”. So the first one is blocked, and the second one is not.

Original answer which was current 2012:

This solution for popup blocker checking has been tested in FF (v11), Safari (v6), Chrome (v23.0.127.95) & IE (v7 & v9). Update the displayError function to handle the error message as you see fit.

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

Usage:

var popup = window.open("http_www_google_ca", '_blank');
popupBlockerChecker.check(popup);

Hope this helps! :)

I think you need more underscores

In firefox, this displays the blank page and you can't even see the popup blocker message on the opener page. How to close the blank page?

Note that if popup url is a downloadable file(which has Content-Disposition: attachment; in the response header), the popup will close immediately, therefore setTimeout code will fail, and the browser will complain that "Popup Blocker is enabled!". For Chrome, I recommend @ DanielB's solution and it works great.

@ wonsuc when opening a link that has a Content-Disposition: attachment; header you don't need to open it in a popup. Simply make a direct link to the asset your wanting to download and the native behaviour of the browser will allow you to download without redirecting you away from the current page.

@ KevinB I have to say that I'm in a specific situation. I have to download multiple files which are generating PDF files from HTML. And if the HTML contents are large, sometimes it takes several seconds and if I use window.location for it, if the first file takes too long to generate, it will be ignored when the second request started. That's the reason why I have to use window.open, since window.location never lets me know when the response finishes.

One "solution" that will always work regardless of browser company or version is to simply put a warning message on the screen, somewhere close to the control that will create a pop-up, that politely warns the user that the action requires a pop-up and to please enable them for the site.

I know it's not fancy or anything, but it can't get any simpler and only requires about 5 minutes testing, then you can move on to other nightmares.

Once the user has allowed pop-ups for your site, it would also be considerate if you don't overdo the pop-ups. The last thing you want to do is annoy your visitors.

Unfortunately, sometimes all other solutions in this question are not acceptable - only this one. Why? Because they all try to display a popup - not just detect if popups are enabled. What if I want to do it silently?

Something to remember here as well is that a user cannot always just enable popups for your site. In older versions of safari for example, a user can only enable or disable the popup blocker completely, no whitelisting available.

I combined @ Kevin B and @ DanielB's solutions. This is much simpler.

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

Usage:

var popup = window.open('https_www_google_com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}

isPopupBlockerActivated function never returns on return (popupWindow.innerHeight > 0) === false;. You function returns false when your browser is not Chrome. Because onload is asynchronous process. Your function returns false and then onload executed but its result never returns.

A simple approach if you own the child code as well, would be to create a simple variable in its html as below:

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

And then check its existence from parent something similar to following:

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

We wait for some time to make sure that webpage has been loaded, and check its existence. Obviously, if the window did not load after 1500ms then the variable would still be undefined.

how about putting this on window on load handler.

@ bhansa We can't because the check is happening on parent window, whereas the magicNumber variable resides on child window.

I've tried lots of solutions, but the only one I could come up with that also worked with uBlock Origin, was by utilising a timeout to check the closed status of the 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)
}

Obviously this is a hack; like all solutions to this problem.

You need to provide enough time in your setTimeout to account for the initial opening and closing, so it's never going to be thoroughly accurate. It will be a position of trial and error.

Add this to your list of attempts.

For some popup blockers this don't work but i use it as basic solution and add try {} catch

try {
        const newWindow = window.open(url, '_blank');
        if (!newWindow || newWindow.closed || typeof newWindow.closed == 'undefined')         {
            return null;
        }

        (newWindow as Window).window.focus();
        newWindow.addEventListener('load', function () {
            console.info('Please allow popups for this website')
        })
        return newWindow;
    } catch (e) {
        return null;
    }

This will try to call addEventListaner function but if popup is not open then it will break and go to catch, then ask if its object or null and run rest of code.

By using onbeforeunload event we can check as follows

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

it will open 2 black windows in background

the function returns boolean value.

Window.open()

The open() method of the Window interface loads a specified resource into a new or existing browsing context (that is, a tab, a window, or an iframe) under a specified name.

Syntax

open()
open(url)
open(url, target)
open(url, target, windowFeatures)

Parameters

url

(Optional) A string indicating the URL or path of the resource to be loaded. If an empty string ("") is specified or this parameter is omitted, a blank page is opened into the targeted browsing context.

target

(Optional) A string, without whitespace, specifying the name of the browsing context the resource is being loaded into. If the name doesn't identify an existing context, a new context is created and given the specified name. The special target keywords, _self, _blank, _parent, and _top, can also be used.

This name can be used as the target attribute of <a> or <form> elements.

windowFeatures

(Optional) A string containing a comma-separated list of window features in the form name=value — or for boolean features, just name. These features include options such as the window's default size and position, whether or not to open a minimal popup window, and so forth. The following options are supported:

popup

If this feature is enabled, it requests that a minimal popup window be used. The UI features included in the popup window will be automatically decided by the browser, generally including an address bar only.

If popup is not enabled, and there are no window features declared, the new browsing context will be a tab.

Note: Specifying any features in the windowFeatures parameter, other than noopener or noreferrer, also has the effect of requesting a popup.

To enable the feature, specify popup either with no value at all, or else set it to yes, 1, or true.

Example: popup=yes, popup=1, popup=true, and popup all have identical results.

width or innerWidth

Specifies the width of the content area, including scrollbars. The minimum required value is 100.

height or innerHeight

Specifies the height of the content area, including scrollbars. The minimum required value is 100.

left or screenX

Specifies the distance in pixels from the left side of the work area as defined by the user's operating system where the new window will be generated.

top or screenY

Specifies the distance in pixels from the top side of the work area as defined by the user's operating system where the new window will be generated.

noopener

If this feature is set, the new window will not have access to the originating window via Window.opener and returns null.

When noopener is used, non-empty target names, other than _top, _self, and _parent, are treated like _blank in terms of deciding whether to open a new browsing context.

noreferrer

If this feature is set, the browser will omit the Referer header, as well as set noopener to true. See rel="noreferrer" for more information.

Note: Requested position (top, left), and requested dimension (width, height) values in windowFeatures will be corrected if any of such requested value does not allow the entire browser popup to be rendered within the work area for applications of the user's operating system. In other words, no part of the new popup can be initially positioned offscreen.

Description

A WindowProxy object. The returned reference can be used to access properties and methods of the new window as long as it complies with the same-origin policy security requirements.

The Window interface's open() method takes a URL as a parameter, and loads the resource it identifies into a new or existing tab or window. The target parameter determines which window or tab to load the resource into, and the windowFeatures parameter can be used to control to open a new popup with minimal UI features and control its size and position.

Note that remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing. The window creation and the loading of the referenced resource are done asynchronously.

How do I delimit a databound Javascript string parameter in ASP . NET?

Javascript string parameter in ASP . NET

Triple Quotes? How do I delimit a databound Javascript string parameter in ASP . NET? How do I delimit a Javascript data-bound string parameter in an anchor OnClick event? I have an anchor tag in an ASP . NET Repeater control. The OnClick event of the anchor contains a call to a Javascript function. The Javascript function takes a string for its input parameter. The string parameter is populated with a data-bound value from the Repeater. I need the "double quotes" for the Container.DataItem . I need the 'single quotes' for the OnClick . And I still need one more delimiter (triple quotes?) for the input string parameter of the Javascript function call. Since I can't use 'single quotes' again, how do I ensure the Javascript function knows the input parameter is a string and not an integer? Without the extra quotes around the input string parameter, the Javascript function thinks I'm passing in an integer. The anchor: <a id="aShowH…

Read more…

ASP . NET Custom Client-Side Validation

Client-Side Validation

I have a custom validation function in JavaScript in a user control on a .Net 2.0 web site which checks to see that the fee paid is not in excess of the fee amount due. I've placed the validator code in the ascx file, and I have also tried using Page.ClientScript.RegisterClientScriptBlock() and in both cases the validation fires, but cannot find the JavaScript function. The output in Firefox's error console is "feeAmountCheck is not defined" . Here is the function (this was taken directly from firefox->view source) <script type="text/javascript"> function feeAmountCheck(source, arguments) { var amountDue…

Read more…

Multiply | JavaScript (solved) | codewars

Multiply - JavaScript (Solved) - codewars

This code does not execute properly. Try to figure out why. Solution function multiply(a, b) { return a * b; } Multiplication The multiplication of whole numbers may be thought of as repeated addition; that is, the multiplication of two numbers is equivalent to adding as many copies of one of them, the multiplicand, as the quantity of the other one, the multiplier. Both numbers can be referred to as factors. Example: 3 * 4 = 4 + 4 + 4 = 12 return The return statement…

Read more…