window.focus() not working in Google Chrome

Just wondering if Google Chrome is going to support window.focus() at some point. When I mean support, I mean have it work. The call to it doesn't fail, it just doesn't do anything. All other major browsers do not have this problem: FireFox, IE6-IE8 and Safari.

I have a client-side class for managing browser windows. When I first create a window the window comes into focus, but subsequent attempts to bring focus to the window do not work.

From what I can tell, this appears to be a security feature to avoid annoying pop-ups and it does not appear to be a WebKit issue as it works in Safari.

I know one idea someone brought forward was to close the window then reopen it, but this is a horrible solution. Googling shows that I do not appear to be the only person frustrated with this.

And just to be 100% clear, I mean new windows, not tabs (tabs cannot be focused from what I've read) and all the windows being opened are in the same domain.

Any ideas, workarounds aside from the bad one I mention above?

There is a bug logged on the Chromium project about this, check it out here. Thanks for posting that Rich.

MyCompany = { UI: {} }; // Put this here if you want to test the code. I create these namespaces elsewhere in code.

MyCompany.UI.Window = new function() {
    // Private fields
    var that = this;
    var windowHandles = {};

    // Public Members
    this.windowExists = function(windowTarget) {
        return windowTarget && windowHandles[windowTarget] && !windowHandles[windowTarget].closed;
    }

    this.open = function(url, windowTarget, windowProperties) {
        // See if we have a window handle and if it's closed or not.
        if (that.windowExists(windowTarget)) {

            // We still have our window object so let's check if the URLs is the same as the one we're trying to load.
            var currentLocation = windowHandles[windowTarget].location;

            if (
                (
                    /^http(?:s?):/.test(url) && currentLocation.href !== url
                )
                    ||
                (
                    // This check is required because the URL might be the same, but absolute,
                    // e.g. /Default.aspx ... instead of http://localhost/Default.aspx ...
                    !/^http(?:s?):/.test(url) &&
                    (currentLocation.pathname + currentLocation.search + currentLocation.hash) !== url
                )
            ) {
                // Not the same URL, so load the new one.
                windowHandles[windowTarget].location = url;
            }

            // Give focus to the window. This works in IE 6/7/8, FireFox, Safari but not Chrome.
            // Well in Chrome it works the first time, but subsequent focus attempts fail,. I believe this is a security feature in Chrome to avoid annoying popups.
            windowHandles[windowTarget].focus();
        }
        else
        {
            // Need to do this so that tabbed browsers (pretty much all browsers except IE6) actually open a new window
            // as opposed to a tab. By specifying at least one window property, we're guaranteed to have a new window created instead
            // of a tab.
            windowProperties = windowProperties || 'menubar=yes,location=yes,width=700, height=400, scrollbars=yes, resizable= yes';
            windowTarget = windowTarget || "_blank";

            // Create a new window.
            var windowHandle = windowProperties ? window.open(url, windowTarget, windowProperties) : window.open(url, windowTarget);

            if (null === windowHandle) {
                alert("You have a popup blocker enabled. Please allow popups for " + location.protocol + "//" + location.host);
            }
            else {
                if ("_blank" !== windowTarget) {
                    // Store the window handle for reuse if a handle was specified.
                    windowHandles[windowTarget] = windowHandle;
                    windowHandles[windowTarget].focus();
                }
            }
        }
    }
}

Answers


Still the same in version 14.0.835.202 m on Windows 7; found another workaround, not more elegant but at least will avoid losing data on the page: show an alert in the window you want to focus.


I've been struggling with this issue. I wanted a reference to another window, so I was issuing a:

otherWinRef = window.open("","OtherWindow");

However when I issue this command, the browser will switch focus to the OtherWindow. I thought this could be addressed by doing this:

otherWinRef = window.open("","OtherWindow");
window.focus();

but the window.focus() has no effect. I tried:

otherWinRef = window.open("","OtherWindow");
setTimeout(window.focus,0);

But the window.focus() call still had no effect.

I resolve the issue by adding the following code to the OtherWindow's source.

function Bounce(w) {

        window.blur();
        w.focus();
}

Then I changed the code in the main window to:

otherWinRef = window.open("","OtherWindow");
otherWinRef.Bounce(window);

UPDATE: This solution appears to no longer work in Chrome.

Unbelievably, the solution is quite simple. I've been trying to figure this issue out for at least a week. All you need to do is blur the window then give it focus. I had tried this previously and it didn't work.

windowHandle.blur();
windowHandle.focus();

So I ended up trying this instead:

windowHandle.blur();
setTimeout(windowHandle.focus, 0);

and that seems to work.

I've updated my code here:

MyCompany = { UI: {} }; // Put this here if you want to test the code. I create these namespaces elsewhere in code.

MyCompany.UI.Window = new function() {       
    // Private fields
    var that = this;
    var windowHandles = {};
    var isChrome = /chrome/.test(navigator.userAgent.toLowerCase());

    // Public Members
    this.focus = function(windowHandle) {
        if (!windowHandle) {
            throw new Exception("Window handle can not be null.");
        }

        if (isChrome) {
            windowHandle.blur();
            setTimeout(windowHandle.focus, 0);                    
        }
        else {
            windowHandle.focus();
        }    
    }

    this.windowExists = function(windowTarget) {
        return windowTarget && windowHandles[windowTarget] && !windowHandles[windowTarget].closed;
    }

    this.open = function(url, windowTarget, windowProperties) {
        // See if we have a window handle and if it's closed or not.
        if (that.windowExists(windowTarget)) {

            // We still have our window object so let's check if the URLs is the same as the one we're trying to load.
            var currentLocation = windowHandles[windowTarget].location;

            if (
                (
                    /^http(?:s?):/.test(url) && currentLocation.href !== url
                )
                    ||
                (
                    // This check is required because the URL might be the same, but absolute,
                    // e.g. /Default.aspx ... instead of http://localhost/Default.aspx ...
                    !/^http(?:s?):/.test(url) &&
                    (currentLocation.pathname + currentLocation.search + currentLocation.hash) !== url
                )
            ) {
                // Not the same URL, so load the new one.
                windowHandles[windowTarget].location = url;
            }

            // Give focus to the window. This works in IE 6/7/8, FireFox, Safari but not Chrome.
            // Well in Chrome it works the first time, but subsequent focus attempts fail,. I believe this is a security feature in Chrome to avoid annoying popups.
            that.focus(windowHandles[windowTarget]);
        }
        else {
            // Need to do this so that tabbed browsers (pretty much all browsers except IE6) actually open a new window
            // as opposed to a tab. By specifying at least one window property, we're guaranteed to have a new window created instead
            // of a tab.
            //windowProperties = windowProperties || 'menubar=yes,location=yes,width=700, height=400, scrollbars=yes, resizable= yes';
            windowProperties = windowProperties || 'menubar=yes,location=yes,width=' + (screen.availWidth - 15) + ', height=' + (screen.availHeight - 140) + ', scrollbars=yes, resizable= yes';
            windowTarget = windowTarget || "_blank";

            // Create a new window.
            var windowHandle = windowProperties ? window.open(url, windowTarget, windowProperties) : window.open(url, windowTarget);

            if (null === windowHandle || !windowHandle) {
                alert("You have a popup blocker enabled. Please allow popups for " + location.protocol + "//" + location.host);
            }
            else {
                if ("_blank" !== windowTarget) {
                    // Store the window handle for reuse if a handle was specified.
                    windowHandles[windowTarget] = windowHandle;
                    windowHandles[windowTarget].focus();
                }
            }
        }
    }
}

A suggestion from someone's blog is to use this:

if (navigator.userAgent.indexOf('Chrome/') > 0) {
    if (window.detwin) {
        window.detwin.close();
        window.detwin = null;
    }
}
window.detwin = window.open(URL,  'windowname', '...');
window.detwin.focus();

Following this bug might be useful.


you can focus another window by calling open with javascript:; as url parameter:

window.open('http://....', 'myWindow');

// focus that window later on...
window.open('javascript:;', 'myWindow');

Here's a workaround I was able to use. It may not work for everybody, but it does what I need it to, and it does handle scenarios where your popup has been updated via Ajax after the initial load (ie - it doesn't go back to the server to reload the page).

function refocusWindow() {
  var newName = window.name + '-2'; // you'll want to customize this for your needs
  var options = ''; // again, customize for your situation
  var w = window.open('', newName, options);
  w.document.write(document.getElementById('everything').innerHTML);
  window.close();
}    

I'm using the new window trick to make it look like I'm just refocusing the page, but I'm actually creating a new window with the exact contents of the old window and then closing the old window.

You'll just need to make sure that you are able to grab everything you need for the new window. I put everything I need in an #everything div; you may need to change this for your needs.

Hope this at least helps some of you.

Note: inline Javascript seems to execute with this approach, linked Javascript may not. Proceed with caution if this will be a problem for you.


window.focus() for child windows works fine for me on Chrome v52 on Windows, but ONLY inside a user-initiated event, e.g. a click callback. (This is the same restriction that the pop-up blocked applies to window.open() calls.)


The only solution that currently works in Chrome is this code inside new window:

$(".closeBtn").click( function(e) 
{
    window.open("",window.opener.name);
    window.close();
});

Unfortunately the solution only works under two conditions:

  • window.opener has to have it's name set on document load (window.name="WhateverName";)
  • window.open() is called on user click

I just found out a quite simple solution.

If you reopen a window that is in a background position, targeting the same window ("_self"), Chrome automatically focus that window.

To regain focus of a window you should use the following code:

path = windowHandle.document.URL;
windowHandle.open(path,"_self");

This works fine for me. Removed launching blank window from catch block, instead launching the url directly, which avoids user's confusion when he says blank window.

windowHandle = window.open('', 'PrintInvoice', urlOptions);
try {
    windowHandle.document.location.href = url;
} catch (exc) {
    windowHandle.close();
    windowHandle = window.open(url, 'PrintInvoice', urlOptions);
}
windowHandle.focus();

I fought this in Chrome. I wanted a popup window to display when the user clicked a link on the parent screen. Works the first time the popup window is displayed, but once the popup loses focus, javascript can't bring it back to the front again; you must manually click on the window. Here is what worked for me. This script is the parent window (the one with the links). As you can see, I put it at the end of the HEAD section::

<script type="text/javascript">
  var infoWindow;

  function openLink(url)   {
    infoWindow = window.open("", "infoWindow", "width=880, height=500, top=20, left=20, scrollbars=yes, toolbar=yes, resizable=yes");
    infoWindow.location.href=url;
    infoWindow.focus();
  }

  function closeWindow()   {
    if (infoWindow)   {
      infoWindow.close();
    }
  }
</script>
</head>
<body bgcolor="black" onFocus="closeWindow()" onLoad="closeWindow()">

All links are <A href="Javascript: openLink('url')">. If the user does not close the popup window manually, it is closed when the parent window regains focus. So the popup is destroyed and re-created every time. Seems kinda convoluted, but it works for me.


Maybe not what everyone wants either, but (in chrome) I noticed that an alert raised from the pop uped page keeps hold on the focus of the popup. So I'm doing this now...

On the pop uped page, have a function loaded in the header:

<script type="text/javascript">
    function confirmBlur() {
        if (confirm("Do you want to close this window?")) {
            window.close();
        }
    }
</script>`

And then on the pop uped page:

<body onblur="ConfirmBlur()">

So this is a variant of closing the popup when the focus is lost. But in my case, the popup is an edit window for data. A window, one doesn't want to close unasked. So now the user gets notified the focus is about to drop and gets a choice if he wants to close the window or not. Again, far from perfect, but it worked for me.

(be gentle)


None of the solutions here worked for me. So, I came up with this:

$('<form target="_blank" action="'+URL+'" method="post"></form>')
    .appendTo('body').submit();

This creates a blank form that is submitted via post to the target URL. By applying target="_blank" we mimic calling window.open() with the side effect of maintaining focus on the new window.

Edit: Vanilla JS version that also removes the form element afterwards:

var f = document.createElement("form");
f.setAttribute('method', 'post');
f.setAttribute('action', URL);
f.setAttribute('target', '_blank');
document.getElementsByTagName('body')[0].appendChild(f);
f.submit();
f.parentNode.removeChild(f);

window.open('javascript:void(0)', 'myWindow');

Need Your Help

Swing - huge spaces between objects

java swing jpanel layout-manager grid-layout

I am creating a program using java swing components. when using the components i am creating a text editor. i am using buttons instead of a menu to be able to load/save. when i am trying to implemet

SONAR importing cobertura.ser coverage reports to sonar server using mvn sonar:sonar?

maven sonarqube cobertura

I have a cobertura.ser file, that got generated while integration-test and system test. Now I want to import my coverage this to sonar server.