开发者

window.focus() not working in Google Chrome

开发者 https://www.devze.com 2022-12-29 13:46 出处:网络
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

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 && windowHand开发者_StackOverflow社区les[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();
                }
            }
        }
    }
}


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


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.


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


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


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.


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.


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


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


I simply use this line of code here to refocus, it's the best thing that's worked for me so far:

    window.open('', 'NameOfTheOpenedWindow').focus();

thanks to this answer here

I also made a jsfiddle for testing.

I hope this helps


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.


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


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


I was only able to solve my problem when I used setTimeout() and encapsulated the focus() inside an anonymous function. Here is an example:

setTimeout(function () {
   myField.focus();
}, 0);


My good friends! Haha! There is only ONE way to focus a window (bring to front) in google chrome automatically. This complicated method took me a long time to find. So please share this method with others!

My problem was I wanted my google chrome extension to open in a new window when I click on it. However, google chrome does not want unknown windows to focus automatically. So It would open the window minimized.

I wanted it to open not minimized, but every piece of code that would do that would also glitch it and break the window. But I found a workaround.

Any peace of code with window.focus will NOT WORK IN CHROME:

window.focus   //DOES NOT WORK IN CHROME!!

To focus the window, you have to make a button that opens the window and then click that button using javascript.

Button HTML:

<button class='open' id='open' onclick='open()'></button>

You can make the button invisible in CSS:

.open {
ocupacity: 0;
margin-bottom: 0px;
margin-top: 0px;
padding-bottom: 0px;
padding-top: 0px;
}

This js code is to make sure that it only opens every 2 times, because if the js code opens in a new window, then it counts as opening twice:

open = localStorage.getItem('open')
if (open == 1){                            //1 is don't open window
    localStorage.setItem('open',0)    
} else {                                   //0 is open window
    setTimeout(function(){           //Set timeout lets the page load first
        var openbutton = document.getElementById("open");
        openbutton.click()                 // Clicks the button
    }, 1);
    localStorage.setItem('open',1)
}

This js code is the function that opens it in a new window, but since it is being opened by a button it will open normally:

open() {
    window.close();      //closes the chrome extension popup
    window.open(document.URL, '_blank', 'location=yes,height=653,width=400,scrollbars=no,status=yes');   //opens it in new window
}


The problem is that if you pass the same name to window.open(url,name,features) in Chrome more than once, Chrome recognizes that it is already open which is fine, but it won't focus it no matter what you do.

Chrome will however return the handle of the existing window, so you can then close it and reopen it. At that point focusing will be superfluous.

Here is what worked for me:

    var win=window.open(url,name,features);
    win.close();
    var win=window.open(url,name,features);

// where url, name and features are variables.

This works fine regardless of whether or not the window is already open.

Note: if you change the window name each time by using the time or a random number or the url itself, the window will open in focus, but you will get a new window every time and they can accumulate. If you want to keep using the same window to display different urls, just keep using the same window name.

I use this for displaying archived Vendor Invoice pdfs where the url is for each is stored in a table. If you keep opening one after another, you want to use the same window but have it focus when you access it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号