Javascript window.focus() 在谷歌浏览器中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2758608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:48:27  来源:igfitidea点击:

window.focus() not working in Google Chrome

javascriptgoogle-chromecross-browserdom-events

提问by nickytonline

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.

只是想知道谷歌浏览器是否会window.focus()在某个时候支持。当我的意思是支持时,我的意思是让它发挥作用。对它的调用不会失败,它只是什么都不做。所有其他主流浏览器都没有这个问题:FireFox、IE6-IE8 和 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.

据我所知,这似乎是一项安全功能,可以避免烦人的弹出窗口,而且它似乎不是 WebKit 问题,因为它可以在 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.

为了 100% 清楚,我的意思是新窗口,而不是选项卡(选项卡无法从我读过的内容中获得焦点),并且所有打开的窗口都在同一个域中。

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.

Chromium 项目中记录了一个关于此的错误,请在此处查看。感谢您发布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();
                }
            }
        }
    }
}

回答by Aheho

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:

但 window.focus() 没有效果。我试过:

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

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

但是 window.focus() 调用仍然没有效果。

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

我通过将以下代码添加到 OtherWindow 的源代码来解决该问题。

function Bounce(w) {

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

Then I changed the code in the main window to:

然后我将主窗口中的代码更改为:

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

回答by Sti

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.

在 Windows 7 版本 14.0.835.202 m 中仍然相同;找到了另一种解决方法,不是更优雅,但至少可以避免丢失页面上的数据:在要聚焦的窗口中显示警报。

回答by nickytonline

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

更新:此解决方案似乎不再适用于 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();
                }
            }
        }
    }
}

回答by pwolaq

you can focusanother window by calling openwith javascript:;as urlparameter:

您可以focus通过open使用javascript:;asurl参数调用另一个窗口:

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

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

回答by Rich Bradshaw

A suggestion from someone's blogis 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 bugmight be useful.

关注这个错误可能会有用。

回答by tobinibot

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

这是我能够使用的解决方法。它可能不适用于所有人,但它可以满足我的需要,并且它确实处理了在初始加载后通过 Ajax 更新弹出窗口的情况(即 - 它不会返回服务器重新加载页面) .

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 #everythingdiv; you may need to change this for your needs.

您只需要确保能够获取新窗口所需的一切。我把我需要的一切都放在一个#everythingdiv 中;您可能需要根据需要更改此设置。

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.

注意:内联 Javascript 似乎用这种方法执行,链接的 Javascript 可能不会。如果这对您来说是个问题,请谨慎操作。

回答by Rich

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

window.focus()对于子窗口,我在 Windows 上的 Chrome v52 上工作正常,但仅在用户启动的事件中,例如单击回调。(这与阻止弹出窗口适用于window.open()呼叫的限制相同。)

回答by Matej Balanti?

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

当前适用于 Chrome 的唯一解决方案是新窗口中的以下代码:

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

Unfortunately the solution only works under two conditions:

不幸的是,该解决方案仅适用于两种情况:

  • window.openerhas to have it's name set on document load (window.name="WhateverName";)
  • window.open()is called on user click
  • window.opener必须在文档加载时设置它的名称 ( window.name="WhateverName";)
  • window.open()在用户点击时调用

回答by Raposo

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.

如果您重新打开一个位于背景位置的窗口,目标是同一窗口(“_self”),Chrome 会自动聚焦该窗口。

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

要重新获得窗口焦点,您应该使用以下代码:

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

回答by Praveena M

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.

这对我来说很好用。去掉了catch块的启动空白窗口,改为直接启动url,避免用户说空白窗口时的混淆。

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