window.focus()不能在Google Chrome中使用

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

我有一个用于pipe理浏览器窗口的客户端类。 当我第一次创build一个窗口时,窗口变得焦点了,但随后尝试将焦点移到窗口上不起作用。

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

我知道有人提出的一个想法是closures窗口,然后重新打开它,但这是一个可怕的解决scheme。 谷歌search表明,我似乎并不是唯一受挫的人。

为了100%清楚,我的意思是新的窗口,而不是标签(选项卡不能从我所读的焦点),所有打开的窗口都在同一个域。

除了上面提到的那个不好的想法之外,还有什么想法和解决办法?

Chromium项目上有一个buglogging在这里 。 感谢您发布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, // eg /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(); } } } } } 

Windows 7上的14.0.835.202版本仍然如此; 发现另一个解决方法,不是更优雅,但至less可以避免丢失页面上的数据:在你想要关注的窗口中显示一个警报。

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

令人难以置信的是,解决scheme非常简单。 我一直在试图解决这个问题至less一个星期。 所有你需要做的是模糊窗口,然后给它的焦点。 我曾经尝试过,并没有奏效。

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

我一直在努力解决这个问题。 我想参考另一个窗口,所以我发出一个:

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

某人的博客的build议是使用这个:

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

以下这个bug可能是有用的。

这是我可以使用的解决方法。 它可能不适用于每个人,但它做我所需要的,并且它处理的情况下popup已更新通过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(); } 

我使用新的窗口技巧,使它看起来像我只是重新调整页面的焦点,但我实际上是创build一个新的窗口与旧窗口的确切内容,然后closures旧窗口。

你只需要确保你能够抓住所有你需要的新窗口。 我把所有我需要的东西放在一个#everything 。 你可能需要改变这个你的需求。

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

注意 :内联JavaScript似乎执行这种方法,链接的Javascript可能不会。 谨慎行事,如果这会对您造成问题。

目前在Chrome中工作的唯一解决scheme是在新窗口中的代码:

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

不幸的是,这个解决scheme只能在两个条件

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

窗口的window.focus()对于Windows上的Chrome v52可以正常工作,但只能在用户启动的事件中进行,例如点击callback。 (这与popup窗口被阻止的限制适用于window.open()调用)。

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

如果您重新打开处于背景位置的窗口,并将其定位到相同的窗口(“_self”),则Chrome会自动对该窗口进行对焦。

要重新获得一个窗口的焦点,你应该使用下面的代码:

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

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

我在Chrome中打了这个。 我想要一个popup窗口,当用户点击父屏幕上的链接时显示。 第一次popup窗口时显示,但一旦popup失去焦点,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')"> 。 如果用户没有手动closurespopup窗口,则在父窗口重新获得焦点时closures。 所以popup窗口每次都被销毁并重新创build。 似乎有点复杂,但它适用于我。

也许不是每个人都想要的,但是(在铬)我注意到从popup页面引发的警报保持popup窗口的焦点。 所以我现在正在做这个…

在popup的页面上,在头文件中加载一个函数:

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

然后在popup的页面上:

 <body onblur="ConfirmBlur()"> 

所以这是一个closurespopup窗口焦点丢失的变种。 但在我的情况下,popup窗口是数据的编辑窗口。 一个窗口,一个不想closures未询问。 所以,现在用户得到通知,关注焦点即将下降,如果他想closures窗口,可以select。 再次,远非完美,但它为我工作。

(要温柔)

你可以通过调用javascript:; open另一个窗口javascript:; 作为url参数:

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