如何获取所有已打开子窗口的引用

28

我想获取所有已经打开的子窗口的引用,有什么办法吗?我不是使用 child = window.open(....),而是使用 window.open(....) 打开多个子窗口。


1
如果你在创建它们时没有存储它们,那就太晚了。 - RobG
4个回答

61
如果你不想改变你现有的代码,你可以简单地覆盖 window.open() 函数:
var openedWindows = [];
window._open = window.open; // saving original function
window.open = function(url,name,params){
    openedWindows.push(window._open(url,name,params));
    // you can store names also...
}

在调用window.open()之前运行此代码。打开的窗口的所有引用都将存储在openedWindows数组中。您可以随时访问它们。

运行此代码以在调用 window.open() 之前生成一个新的、空的数组,以便在执行后续操作时使用该数组来跟踪打开的窗口。

var openedWindows = [];

4
@Govind:这个解决方案需要注意一点 - 它是一种hack,最好避免以防止未来的维护问题。请参见:https://dev59.com/HG025IYBdhLWcg3wFxya#6223589 - rahulmohan
当然!为了避免未来的问题,最好将我编写的函数重命名为window.open2() :) 并将所有现有的.open()调用更改为.open2()。但是看起来@Govind不想在他的代码中做任何更改... - Hrant Khachatrian
1
问题在于,当我们刷新主窗口时,打开的窗口中的所有数据都会丢失。有什么办法可以避免这种情况吗? - Rodrigo
为了不破坏依赖于默认行为的任何代码,这个更改后的window.open()在存储到数组中后也应该返回引用。 - z-boss
你应该实际执行 window._open.apply(window, arguments),因为传递 undefined 作为参数和不传递任何参数会产生不同的行为。我相信明确传递 undefined 将禁用所有窗口功能。 - pushkin

19

我不认为你可以这样做,除非你知道窗口的名称,而我猜你不知道它们的名称。(如果你知道它们的名称,你可以使用window.open("", "name")来获取对它们的引用。)

更好的选择当然是事先记住从window.open返回的引用—— 但你已经知道了。:-)


+1 很好的回答,但我有这种方法的要求。 - Govind Malviya
@Govind: 已经了解。不幸的是,除了保存返回值或知道分配给它们的名称以便稍后使用window.open("", "name")检索它们之外,我不认为有第三种选择。 - T.J. Crowder

2

好的,我使用Oracle CRM onDemand中的答案来禁用弹出窗口中的一个选择项,并从父窗口执行脚本,然后它就起作用了!(我无法控制弹出窗口的生成,它们是由应用程序框架打开的)

让我们看看我是怎么做到的:

背景:在详细页面中,用户可以通过单击放大镜图标 >>> 添加一些信息,然后会打开一个包含搜索表单的新窗口,但是一个选择项正在困扰管理员:如果用户更改其默认值,则他/她将获得对禁止记录的访问权限!!我的天啊!

第一种方法: 立即禁用该选择项!

尝试:我使用浏览器的开发工具(F12)找到了图片的onclick属性。那里有一个openAssocPopup方法,然后我知道了子窗口的名称:'OccamPopup1' :)

好的!所以让我们进行一些魔法(在父窗口中执行):

window.open("","OccamPopup1").document.getElementById("frmSearch.AQ").setAttribute("disabled", true);

我认为这可能会有帮助,因为这个问题对我也有帮助。你是正确的。现在我正在尝试将子文档对象包装在父级jQuery对象中,以便可以访问整个子DOM...但这是另外一个故事...


1
这并不能防止用户使用Javascript(例如从URL栏)或使用开发工具更改字段值,就像您查找字段的方式一样。如果可能的话,应该通过服务器端代码来防止获取“禁止记录”。 我知道我正在回复一个旧帖子,我想你已经考虑过这些可能性并采取了唯一可用的解决方案。然而,我认为让其他人意识到仅客户端保护的风险是很重要的。 - SimeonJM
是的,你说得对...但是... 1.- Oracle CRM onDemand在云端,我们通过jQuery更改事物,只要我们有一些有限的工具来自定义功能。2.-用户都是新手或JavaScript迷...几乎所有人...我想他们不会像我们(作为他们的提供者,开发团队)那样浪费时间去黑客攻击CRM...即使他们这样做我也不介意... :P 谢谢! - Eugenio F. Martinez Pacheco

0
最好使用前缀和计数器来命名窗口。
我需要检测一个已命名的窗口(即CBCheckout)是否已经打开并使用了以下代码:
var signupWindow = window.open('','CBCheckout','toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=1,height=1');
try {
    if (signupWindow.document.location.href == "about:blank") {
        signupWindow.close();
        signupWindow = undefined;
    }
} catch (e) { }

这将重新获取命名的打开窗口的引用。如果它不存在,您会看到一个小窗口弹出一秒钟。

如果您知道窗口的可能名称,可以循环遍历这些名称,尝试定位它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接