触发从 iframe 到父文档的自定义事件

Posted

技术标签:

【中文标题】触发从 iframe 到父文档的自定义事件【英文标题】:Trigger Custom Event From Iframe To Parent Document 【发布时间】:2012-10-09 16:14:09 【问题描述】:

我在 iframe 中触发自定义事件并从父文档中检测到它时遇到了一些麻烦。 iframe 和父文档都具有相同的来源(相同的协议、相同的主机、相同的端口)。

有什么建议吗?

【问题讨论】:

请写清楚the same source是什么。 你可以从你的 iframe 调用 parent.functionname()。 同一个协议,同一个主机,同一个端口 如果父窗口在不同的域中,则无法从子 iframe 引发父窗口上的事件。 【参考方案1】:

我遇到了类似的问题,用window.postMessage解决了。

目前,API 仅支持传递字符串,但如果您修改您的解决方案,它会很强大。更多详情here

来自源页面(被 iframe 使用): postMessage API 需要 2 个参数 - 消息,目标

例如:window.parent.postMessage("HELLO_PARENT", 'http://parent.com');

从父页面(包含 iframe。例如容器):

    像往常一样添加事件监听器

     window.addEventListener('message', handleMessage, false);
    

    使用 event.origin 检查定义您的函数(出于安全考虑)\

     function handleMessage(event)   
         if (event.origin != "http://child.com")  return;   
         switch(event.data)    
              case "HELLO_PARENT":  
                 alert("Hello Child");  
                 break;  
          
     
    

【讨论】:

我在每个 IE 和 Edge 中传递对象时遇到了麻烦 @FarzadYZ - 您的评论似乎与 what MDN says 相矛盾:“window.postMessage() 方法可以安全地启用跨域通信。” JSON.stringify(yourObject) 通过 postMessage 发送 我需要做同样的事情,但内部框架的域与父文档不同。我怎样才能做到这一点?【参考方案2】:

这行得通:

parent.$('body').trigger('eventName');

在 iframe 内触发的事件将在父文档中检测到。

【讨论】:

如果父页面不包含jQuery怎么办? 您可以使用window.addEventListener,如下所示。【参考方案3】:

同时支持同域和跨域 iframe 的一致答案是使用事件系统。

目标是从 iframe 向父级发送自定义事件。

在 iframe 源文件中:

var myCustomData =  foo: 'bar' 
var event = new CustomEvent('myEvent',  detail: myCustomData )
window.parent.document.dispatchEvent(event)

并将其添加到包含 iframe 的父文件中:

window.document.addEventListener('myEvent', handleEvent, false)
function handleEvent(e) 
  console.log(e.detail) // outputs: foo: 'bar'

【讨论】:

我可以检查这对跨域 iframe 是如何工作的吗? window.parent.document 抛出 CORS 错误(在跨域 iframe 的情况下)。 它对我不起作用。我处于 Angular 6 环境中。也许有什么东西阻碍了这种交流,不确定。【参考方案4】:

我也找到了用 jquery 解决这个问题的方法:

在父文件中:

<body>
        <iframe src="something.html"></iframe>

</body>

<script>
 window.document.addEventListener('event', function(e)
            console.log("event:" + e.detail);
            $("iframe").contents().find(".class[title='" + e.detail + "']").css(someChanges);
</script>

所以您不需要在您的 iFrame 中添加任何其他 EventListener

当然,也许你想看看我的 CustomEvent:

var test  = "1";
var event = new CustomEvent('event',  detail: test )
                window.document.dispatchEvent(event);

我希望我能帮助别人......

【讨论】:

以上是关于触发从 iframe 到父文档的自定义事件的主要内容,如果未能解决你的问题,请参考以下文章

javascript中带有自定义触发器的自定义事件

如何测试从子组件触发的自定义事件

jquery的自定义事件通过on绑定trigger触发

DOM3中的自定义事件

JS 当html改变时触发事件

jQuery 的自定义事件