window.opener.focus()不起作用

时间:2013-08-29 01:52:08

标签: javascript browser window

我似乎无法让它发挥作用。

响应点击,窗口A打开窗口B(然后有焦点)。然后,响应点击B,窗口调用window.opener.focus(),但焦点返回A。

我发现Chrome有一个奇怪的,奇怪的解决方法(29,可能是其他人)。 如果我跑:

window.opener.name = 'somename';
window.open(window.opener.location.href, window.opener.name);
window.opener.focus();

它确实有效(并且不会重新加载窗口A)。但这对Firefox不起作用,无论如何它可能都是侥幸。

我似乎很清楚openerfocus 假设要做什么,但window.opener.focus()不起作用。我错过了什么?

4 个答案:

答案 0 :(得分:5)

来自fine manual

  

使请求将窗口置于最前面。它可能由于用户设置而失败,并且在此方法返回之前不保证窗口位于最前面。

强调我的。调用focus()只是一个请求,浏览器可以自由地忽略您,您通常应该被忽略。如果您需要某些理由说明浏览器会忽略您的请求,请考虑在有人打字时将焦点切换到一个小窗口,从而了解您可以采取哪些各种邪恶的事情。

如果您需要focus()为您的应用程序工作,那么您需要重新设计您的应用程序,以便它不需要致电focus()

答案 1 :(得分:2)

我可以看到为什么浏览器/操作系统不允许子窗口接管焦点(滥用权力)。这是一个解决方法:

  1. 在父窗口中,声明“window.external”中将触发Javascript“alert()”或“confirm()”的函数。
  2. 从子窗口调用该函数。
  3. 浏览器可能会忽略来自想要控制焦点的子窗口的请求(例如window.opener.focus()),但浏览器应该尊重来自父窗口的请求,该窗口会触发alert()或确认()动作,需要关注父窗口。
  4. JS Parent:

        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:

        // assuming you have jQuery
        $('.btn').click() {
            window.opener.external.comeback();  
        };
    

    - 我在现实世界的应用程序中使用此代码来处理在子窗口中运行的结帐请求,我需要优雅地返回到父窗口。

    请参阅: SimplifySites.com

答案 2 :(得分:1)

面向网络或私人内部网?

窗口管理取决于浏览器和操作系统。 HTML& ECMAscript没有什么可说的。

如果这是面向公众的网站,那就不要打扰 - 正如他们所说,“不要破坏网络。”

但我真的很想!

如果这是针对某种严格管理(比如说Intranet)的应用程序,那么你需要求助于编写Addons / Extensions。如果你可以将自己限制在一个浏览器和放大器中,这肯定会更容易。平台。

编辑:Win32上的Firefox示例...

此解决方案可用作Firefox的自定义插件,在内部使用jsctypes加载Win32 DLL。公开了window_focus() JavaScript函数,它可以实现您想要的功能。

此解决方案有3个部分:

  1. 加载/绑定Win32 API的特权JavaScript代码
  2. 外部DLL的CPP头文件
  3. 外部DLL的CPP源文件
  4. 我在MSVC ++中构建了一个简单的GUI DLL项目,后面有两个文件&编译wmctrl.dll,取决于msvcr100.dll,并使用Dependency Walker查找DLL导出的“plain C”符号以供js-ctypes使用。例如:?wmctrl_find_window@@YAKPAD@Z是名为wmctrl_find_window的C ++ api函数的“普通C”符号。

    作为一个警告,此代码依赖于暂时能够更改需要关注的窗口的标题,以便Win32 API可以检查桌面上的所有窗口以找到正确的Firefox窗口。

    您需要访问特权Mozilla平台API,即:Firefox Addon中的JavaScript。

    在您的特权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

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

答案 3 :(得分:0)

解决方法 在主窗口中添加了脚本功能:

    function here() {
        alert('Welcome Back')  // seems needed to wake up document
        window.focus()
    }

在打开的窗口中调用脚本功能:

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

在不同的浏览器中工作方式大不相同 有些将使父选项卡闪烁 有些标记了父选项卡,您必须注意它 有些您必须第一次单击主页选项卡,然后您可以授予它直接进入主页选项卡的权限,而无需确认框。