window.focus()无法在Google Chrome中使用

时间:2010-05-03 14:09:47

标签: javascript javascript-events cross-browser google-chrome

只是想知道Google Chrome是否会在某个时候支持window.focus()。当我的意思是支持时,我的意思是让它发挥作用。对它的调用不会失败,它只是没有做任何事情。所有其他主流浏览器都没有这个问题:FireFox,IE6-IE8和Safari。

我有一个用于管理浏览器窗口的客户端类。当我第一次创建一个窗口时,窗口会聚焦,但随后将焦点带到窗口的尝试不起作用。

据我所知,这似乎是一个安全功能,以避免恼人的弹出窗口,它似乎不是一个WebKit问题,因为它在Safari中工作。

我知道有人提出的一个想法是关闭窗户然后重新打开它,但这是一个可怕的解决方案。谷歌搜索表明,我似乎并不是唯一一个对此感到沮丧的人。

只是要100%清楚,我的意思是新窗口,而不是标签(标签不能从我读过的内容中聚焦),所有打开的窗口都在同一个域中。

除了我上面提到的坏事之外,还有任何想法,解决方法吗?

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

16 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:9)

我一直在努力解决这个问题。我想要引用另一个窗口,所以我发出了一个:

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

但是,当我发出此命令时,浏览器会将焦点切换到OtherWindow。我认为这可以通过这样做来解决:

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

但window.focus()无效。我试过了:

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

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

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

function Bounce(w) {

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

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

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

答案 2 :(得分:7)

更新:此解决方案似乎不再适用于Chrome。

令人难以置信的是,解决方案非常简单。我一直在试图解决这个问题至少一周。您需要做的就是模糊窗口然后给它焦点。我之前尝试过这个并没有用。

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

所以我最终尝试了这个:

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

这似乎有效。

我在这里更新了我的代码:

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

答案 3 :(得分:3)

someone's blog的建议是使用此:

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

关注this bug可能会有用。

答案 4 :(得分:3)

您可以focus使用open作为javascript:;参数调用url另一个窗口:

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

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

答案 5 :(得分:2)

这是我能够使用的解决方法。它可能对每个人都不起作用,但是它完成了我需要的工作,它确实处理了在初始加载后通过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();
}    

我正在使用新的窗口技巧使它看起来像我只是重新聚焦页面,但我实际上创建了一个新窗口,其中包含旧窗口的确切内容,然后关闭旧窗口。

您只需要确保能够获取新窗口所需的一切。我把我需要的一切都放在#everything div中;您可能需要根据需要进行更改。

希望这至少可以帮助你们中的一些人。

注意:内联Javascript似乎是用这种方法执行的,链接的Javascript可能没有。如果这对您来说是个问题,请务必小心。

答案 6 :(得分:2)

子窗口的

window.focus()适用于Windows上的Chrome v52,但仅限于用户启动的事件,例如:点击回调。 (这与弹出窗口阻止适用于window.open()电话的限制相同。)

答案 7 :(得分:1)

目前唯一可在Chrome中使用的解决方案是新窗口中的此代码:

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

不幸的是,该解决方案仅在两种情况下有效:

  • window.opener必须在文档加载(window.name="WhateverName";)上设置名称
  • window.open()在用户点击
  • 时调用

答案 8 :(得分:0)

我刚刚发现了一个非常简单的解决方案。

如果您重新打开处于后台位置的窗口,定位同一窗口(“_ self”),Chrome会自动关注该窗口。

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

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

答案 9 :(得分:0)

这对我来说很好。 从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();

答案 10 :(得分:0)

我在Chrome中打过仗。当用户点击父屏幕上的链接时,我希望显示一个弹出窗口。弹出窗口第一次显示时工作,但一旦弹出窗口失去焦点,javascript就无法再将其恢复到前面;你必须手动点击窗口。这对我有用。此脚本是父窗口(带有链接的窗口)。如您所见,我把它放在HEAD部分::

的末尾
<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()">

所有链接均为<A href="Javascript: openLink('url')">。如果用户未手动关闭弹出窗口,则在父窗口重新获得焦点时将关闭该窗口。因此弹出窗口每次都被销毁并重新创建。看起来有点令人费解,但它对我有用。

答案 11 :(得分:0)

也许不是每个人都想要的,但是(在chrome中)我注意到从pop uped页面引发的警报会保持弹出窗口的焦点。所以我现在正在这样做......

在pop uped页面上,在标题中加载了一个函数:

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

然后在pop pop页面上:

<body onblur="ConfirmBlur()">

因此,这是在焦点丢失时关闭弹出窗口的变体。但就我而言,弹出窗口是数据的编辑窗口。一个窗口,一个不想关闭的窗口。因此,现在用户得到通知,焦点即将放弃,并且如果他想关闭窗口则可以选择。再次,远非完美,但它对我有用。

(温柔)

答案 12 :(得分:0)

这里没有一个解决方案对我有用。所以,我想到了这个:

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

这将创建一个空白表格,该空白表格通过邮寄提交到目标URL。通过应用target="_blank",我们模仿了调用window.open()的副作用,即保持对新窗口的关注。

编辑:Vanilla JS版本,此版本之后也删除了表单元素:

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

答案 13 :(得分:0)

我只是在这里使用这一行代码来重新调整焦点,这是迄今为止对我最有用的东西:

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

在此[[]] {https://stackoverflow.com/a/30758862/10706668“ dileepar的回答”)

我还制作了一个[jsfiddle](https://jsfiddle.net/Foxygaming9978/6gc38f5x/“ jsfiddle弹出窗口重新聚焦测试”)进行测试。

我希望这对您有帮助

答案 14 :(得分:0)

仅当我使用 setTimeout()并将 focus()封装在匿名函数中时,我才能解决问题。这是一个示例:

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

答案 15 :(得分:-1)

window.open('javascript:void(0)', 'myWindow');
相关问题