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

Viewed 122605

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
}

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

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.

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.

Related