javascript window.opener.focus() 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18501095/
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
window.opener.focus() doesn't work
提问by Paul Draper
I can't seem to get this to work.
我似乎无法让它发挥作用。
In response to a click, window A opens window B (which then has focus). Then, in response to a click on B, the window calls window.opener.focus()
, but the focus does notgo back to A.
响应单击,窗口 A 打开窗口 B(然后具有焦点)。然后,响应对B,窗口调用一个点击window.opener.focus()
,但重点不不回A.
I have found a strange, strange workaround for Chrome (29, possibly others). If I run:
我发现了一个奇怪的、奇怪的 Chrome 解决方法(29,可能还有其他的)。如果我运行:
window.opener.name = 'somename';
window.open(window.opener.location.href, window.opener.name);
window.opener.focus();
it does work (and doesn't reload window A). But this doesn't work for Firefox, and it is probably a fluke anyway.
它确实有效(并且不会重新加载窗口 A)。但这对 Firefox 不起作用,无论如何它可能是侥幸。
It seems very clear to me what opener
and focus
are supposedto do, but window.opener.focus()
doesn't work. What am I missing?
在我看来,非常清楚opener
和focus
被认为做的,但window.opener.focus()
不起作用。我错过了什么?
采纳答案by mu is too short
From the fine manual:
从精美的手册:
Makes a requestto bring the window to the front. It may fail due to user settings and the window isn't guaranteed to be frontmost before this method returns.
打造一个请求带来的窗口前。由于用户设置,它可能会失败,并且在此方法返回之前不能保证窗口位于最前面。
Emphasis mine. Calling focus()
is just a request and the browser is free to ignore you and you should generally expect to be ignored. Consider what sorts of nefarious things you could get up to by switching focus to a tiny window while someone is typing if you need some reasons why a browser would ignore your request.
强调我的。调用focus()
只是一个请求,浏览器可以随意忽略您,您通常应该会被忽略。如果您需要一些浏览器会忽略您的请求的原因,请考虑在有人打字时将焦点切换到一个小窗口,您可能会遇到哪些邪恶的事情。
If you need focus()
to work for your application to work then you need to redesign your application so that it doesn't need to call focus()
.
如果您需要focus()
为您的应用程序工作,那么您需要重新设计您的应用程序,以便它不需要调用focus()
.
回答by appcropolis
I can see why a browser/OS will not allow a child windows to take over the focus (abuse of power). Here is a workaround:
我可以理解为什么浏览器/操作系统不允许子窗口接管焦点(滥用权力)。这是一个解决方法:
- In the parent window, declare a function in "window.external" that will trigger Javascript "alert()" or "confirm()".
- Invoke that function from the child window.
- The browser might ignore a request from a child window that wants to control the focus (e.g. window.opener.focus()), but the browser should honor a request from a parent window that triggers an alert() or a confirm() action, which requires to focus on the parent window.
- 在父窗口中,在“window.external”中声明一个将触发Javascript“alert()”或“confirm()”的函数。
- 从子窗口调用该函数。
- 浏览器可能会忽略来自想要控制焦点的子窗口的请求(例如 window.opener.focus()),但浏览器应该接受来自触发 alert() 或 confirm() 动作的父窗口的请求,这需要关注父窗口。
JS Parent:
JS父:
var child = window.open('child.html', 'child');
window.external.comeback = function() {
var back = confirm('Are you sure you want to comback?');
if(back) {
child.close();
} else {
child.focus();
}
}
JS Child:
JS孩子:
// assuming you have jQuery
$('.btn').click() {
window.opener.external.comeback();
};
--I am using this code in a real world application to handle a checkout request that runs in child window, and I need to gracefully return to the parent window.
--我在现实世界的应用程序中使用此代码来处理在子窗口中运行的结帐请求,我需要优雅地返回到父窗口。
See: SimplifySites.com
请参阅: SimplifySites.com
回答by David-SkyMesh
Web-facing or private intranet?
面向 Web 还是私有 Intranet?
Window management is up to the Browser and the OS. HTML & ECMAscript have nothing to say about it.
窗口管理取决于浏览器和操作系统。HTML & ECMAscript 对此无话可说。
If this is for a public-facing website, then just don't bother -- as they say, "Don't break the web."
如果这是面向公众的网站,那么请不要打扰 - 正如他们所说,“不要破坏网络”。
But I really wanna!
但我真的很想!
If this is for some tightly managed (say Intranet) application of some kind then you'll need to resort to writing Addons/Extensions. It's certaintly easier if you can restrict yourself to a single browser & platform.
如果这是针对某种严格管理的(例如 Intranet)应用程序,那么您将需要求助于编写插件/扩展程序。如果您可以将自己限制在单个浏览器和平台上,那肯定会更容易。
EDIT: Example for Firefox on Win32...
编辑:Win32 上的 Firefox 示例...
This solution works as a custom addon for Firefox which uses jsctypes
internally to load a Win32 DLL. The window_focus()
JavaScript function is exposed which does what you want.
此解决方案用作 Firefox 的自定义插件,它在jsctypes
内部用于加载 Win32 DLL。该window_focus()
JavaScript函数所暴露你想要做什么。
There are 3 parts to this solution:
此解决方案有 3 个部分:
- The privileged JavaScript code to load/bind the Win32 APIs
- The CPP header file for our external DLL
- The CPP source file for our external DLL
- 加载/绑定 Win32 API 的特权 JavaScript 代码
- 我们外部 DLL 的 CPP 头文件
- 我们外部 DLL 的 CPP 源文件
I built a simple GUI DLL project in MSVC++ with the later two files & compiled wmctrl.dll
, depending on msvcr100.dll
, and used Dependency Walkerto find the "plain C" symbols exported by the DLL for use by js-ctypes. E.g: ?wmctrl_find_window@@YAKPAD@Z
is the "plain C" symbol for the C++ api function called wmctrl_find_window
.
我在 MSVC++ 中构建了一个简单的 GUI DLL 项目,并使用后面的两个文件进行编译wmctrl.dll
,依赖于msvcr100.dll
,并使用Dependency Walker查找由 DLL 导出以供 js-ctypes 使用的“纯 C”符号。例如:?wmctrl_find_window@@YAKPAD@Z
是 C++ api 函数的“纯 C”符号,称为wmctrl_find_window
.
As a caveat, this code relies on temporarily being able to change the title of the window that needs to be focused so that Win32 APIs can examine all windows on your desktop to find the correct Firefox window.
需要注意的是,此代码依赖于临时能够更改需要聚焦的窗口的标题,以便 Win32 API 可以检查桌面上的所有窗口以找到正确的 Firefox 窗口。
You need to have access to privileged Mozilla platform APIs, i.e: JavaScript inside a Firefox Addon.
您需要有权访问特权 Mozilla 平台 API,即:Firefox 插件中的 JavaScript。
In your privileged JavaScript code:
在您的特权 JavaScript 代码中:
// get API constants (might already be available)
const {Cc,Ci,Cu} = require("chrome");
// import js-ctypes
var file=null, lib=null, ctypes = {};
Cu.import("resource://gre/modules/ctypes.jsm", ctypes);
var ctypes = ctypes.ctypes;
// build platform specific library path
var filename = ctypes.libraryName("wmctrl"); // automatically adds '.dll'
var comp = "@mozilla.org/file/directory_service;1";
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
file.append("browser_code"); // or whereever you put your DLL
file.append(filename);
// get the JavaScript library interface (load the library)
var lib = ctypes.open(file.path);
// wmctrl_find_window: returing unsigned 32bit (long) "window handle"
// takes string "window title".
var find_window = lib.declare(
"?wmctrl_find_window@@YAKPAD@Z", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.uint32_t, /* return type: uint32 */
ctypes.char.ptr); /* parameter: string */
// wmctrl_window_focus: takes unsigned 32bit (long) "window handle".
var window_focus = lib.declare(
"?wmctrl_window_focus@@YAXK@Z", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.void_t, /* return type: void */
ctypes.uint32_t); /* parameter: uint32 */
wmctrldll.h
文件名
#ifdef WMCTRLDLL_EXPORTS
#define WMCTRLDLL_API __declspec(dllexport)
#else
#define WMCTRLDLL_API __declspec(dllimport)
#endif
WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid);
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
wmctrldll.cpp
文件名.cpp
typedef struct {
HWND hWnd;
char title[255];
} myWinSpec;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
char String[255];
myWinSpec* to_find = (myWinSpec*) lParam;
// not a window
if (!hWnd) return TRUE;
// not visible
if (!IsWindowVisible(hWnd)) return TRUE;
// no window title
if (!GetWindowTextA(hWnd, (LPSTR)String, 255)) return TRUE;
// no title match
if (strcmp(String, to_find->title) != 0) return TRUE;
to_find->hWnd = hWnd;
return FALSE;
}
WMCTRLDLL_API void wmctrl_window_focus(unsigned long wid) {
SetForegroundWindow((HWND) wid);
}
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title) {
myWinSpec to_find;
sprintf_s(to_find.title, sizeof(to_find.title), "%s", find_title);
to_find.hWnd = 0;
EnumWindows(EnumWindowsProc, (LPARAM)&to_find);
return (unsigned long) to_find.hWnd;
}
回答by Howard Cary Morris
Workaround In main window added script function:
解决方法在主窗口中添加了脚本功能:
function here() {
alert('Welcome Back') // seems needed to wake up document
window.focus()
}
In opened window invoke script function:
在打开的窗口中调用脚本函数:
function HomeTab() {
O = window.opener;
if (O)
if (O.closed) alert('Home page has been closed')
else O.here()
else alert('This tab has no home page')
}
Works widely differently in different browsers Some will have the parent tab blink Some mark the parent tab, and you have to notice it Some you have to click on home tab the first time and you can then give it permission to go directly to home tab without a confirm box.
在不同浏览器中的工作方式大不相同 有些会使父选项卡闪烁 有些标记父选项卡,您必须注意它 有些您必须第一次单击主页选项卡,然后您可以授予它直接进入主页选项卡的权限,而无需一个确认框。