如何从子窗口发送事件到其父窗口

13

我的主要目标是:

进入我的应用程序,在新选项卡中打开一个链接,在新选项卡中完成一些操作并向父级主选项卡发送事件以进行刷新。

我学习了两种技术,它们并不能完全满足我的需求:

  1. postMessage-据我所知,只能在iframe上使用而不能在选项卡上使用
  2. window.opener - 只能与window.open(url)一起使用,该函数只能打开新窗口而不能打开新选项卡。

如何在选项卡之间传递事件? 我希望JavaScript代码中具有父子关系的具体示例。 它应该适用于跨域(例如:www.mydomain.com和bills.mydomain.com)。

是否有我遗漏的jQuery解决方案?


1
我相信 window.open 应该返回一个新的 Window 对象,如果你没有遇到同源策略的问题,你可以将一个监听器从父级附加到这个对象上,或者设置一个时间间隔来检查某个变量。 - Paul S.
@PaulS.,window.open不会在新标签页中打开。 - Alon
实际上,用户可以决定 window.open() 是在新标签页还是新窗口中打开。浏览器选项中有一个设置来控制这个功能。 - Teemu
它在Chrome中不起作用,但还是谢谢。 - Alon
3个回答

6
以下翻译内容适用于Chrome、Firefox和IE(未测试其他浏览器)。
假设有3个文档:
1. (www.mydomain.com/parent.html)包含链接的“主”文档的页面。 2. (bills.mydomain.com/child.html)将由链接打开的页面。 3. (www.mydomain.com/dispatcher.html)稍后会解释。
首先,将这3个文档的域属性设置为mydomain.com。
<script>
document.domain="mydomain.com";
</script>

在parent.html中创建一个名称为"hiddenframe"的隐藏iframe。同时创建一些函数,以便稍后可以接收响应。
现在,parent.html应该看起来像这样:
<script>
document.domain="mydomain.com";
function fx(msg)//receives the response
{
  alert(msg)
}
</script>
<iframe name="hiddenframe" style="display:none"></iframe>
<a href="http://bills.mydomain.com/child.html" target="_blank">click</a>

在child.html中,你现在可以将一个文档加载到parent.html中隐藏的iframe中。
<script>
document.domain="mydomain.com";
window.open('http://www.mydomain.com/dispatcher.html','hiddenframe');
</script>

请不要对这里使用的window.open()感到困惑,这里不会打开新窗口,页面将加载到parent.html中的iframe中。


在dispatcher.html中,您现在可以调用parent.html中的函数。

<script>
document.domain="mydomain.com";
parent.fx('you just got some response');
</script>

当你只需要重新加载parent.html时,这会更容易一些。

再次在parent.html和child.html中设置document.domain属性(您不需要在parent.html中使用iframe和dispatcher.html)

在parent.html中还设置窗口的name属性,例如

<script>
  window.name="parentTab";
</script>

在child.html中,您现在可以访问parentTab窗口(选项卡)。
<script>
    document.domain="mydomain.com";
    window.open('http://www.mydomain.com/parent.html','parentTab');
</script>

...或者在child.html中的链接或表单中使用"parentTarget"作为目标属性。


0

我为自己做的是,我实现了一些ajax将窗口2中的更改提交到数据库中。我实现了JSON从数据库中拉取新数据返回到窗口1。


0

通过看到类似的问题只谈论window.open(你不想使用),并且据我所知,没有简单的方法可以获取同一域上的所有窗口,对于你想要的,你可能需要编写自己的框架来使用{{link3:window.sessionStorage}}来实现这一点。
我认为你无法访问子域,肯定也无法访问其他域。


使用sessionStorage进行特定于窗口的消息传递的实用想法..
您可以通过URL(GET)传递信息,因此传递消息的一种方法是使父代为自己生成唯一的ID parentID,为其子代生成唯一的ID childID(如果您使用<a>,则将其插入到URL中与parentID一起单击,或者如果您不介意使用<form method="GET">,则使用隐藏字段),然后使用sessionStorage将消息保存到父代,使用类似parentID.childID.timeStamp的键,在父代和子代中都有一个间隔,查找以窗口ID开头的sessionStorage ,然后是.,(即父代查找parentID.)在匹配时将键和值复制到新变量中,删除(以便不再找到),然后按需要解析。

我知道这有点冗长,但我认为作为概念解释要比编写工作示例代码容易得多。


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