附实例!实现iframe父窗体与子窗体的通信

qcloudcommunity · · 933 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

**欢迎大家前往[腾讯云+社区](https://cloud.tencent.com/developer/?fromSource=waitui),获取更多腾讯海量技术实践干货哦~** > 本文由[前端林子](https://cloud.tencent.com/developer/user/2221081)发表于[云+社区专栏](https://cloud.tencent.com/developer/column/5154?fromSource=waitui) 本文主要会介绍如何基于MessengerJS,实现iframe父窗体与子窗体间的通信,传递数据信息。同时本文会提供一个可运行的实例代码,实现在父窗体中,获取到来自子窗体的数据的效果。 # 0.背景介绍 (1)需要在当前的前端项目中,使用iframe嵌套别的站点页面。 (2)当子窗体触发了一个事件后,要给父窗体传一个跳转地址的url。父窗体监听到这个事件后,根据接收到的url,来更新当前父窗体的url,实现页面的跳转。 # 1.采用方案 ## 1.1 MessengerJS方案 可以采用[MessengerJS](https://github.com/biqing/MessengerJS)方案,该方案可以实现父窗体与iframe之间的通信、多个iframe之间的通信。不过要前提是要确保对不同域的页面有修改权限,并且父窗体、子窗体页面都要同时加载这个MessengerJS。 ## 1.2 使用方法 (1) 在需要通信的父窗体、和子窗体的文档中,都需要引入MessengerJS。 (2) 父窗体和子窗体各自的文档(document)中,都需要自己的Messenger与其他文档通信,父窗体和子窗体的window对象都对应着有且仅有一个Messenger对象,该Messenger对象会负责当前window的所有通信任务。因此,**每个Messenger对象都需要唯一的名字**,这样它们之间才可以知道是在跟谁通信。另外,MessengerJS方案**推荐指定项目名称,**(类似命名空间的作用),以增强代码健壮性与组件复用性,避免未来与其他项目冲突。(注意: 项目名称应使用字符串类型) 父窗体与子窗体初始化Messenger对象: ```js // 父窗口中 - 初始化Messenger对象 // 推荐指定项目名称, 避免Mashup类应用中, 多个开发商之间的冲突 var messenger = new Messenger('Parent', 'projectName'); // iframe中 - 初始化Messenger对象 // 注意! Messenger之间必须保持项目名称一致, 否则无法匹配通信 var messenger = new Messenger('iframe1', 'projectName'); // 多个iframe, 使用不同的名字 var messenger = new Messenger('iframe2', 'projectName'); ``` (3) 在发现消息前,目标文档要确保已经监听了消息事件: ```js messenger.listen(function(msg){ alert("收到消息: " + msg); }); ``` (4) 父窗体想给子窗体发信息,要添加消息对象,明确告知当前的父窗体,要发送消息的子窗体的window引用与messenger对象的名字: ```js // 父窗口中 - 添加消息对象, 明确告诉父窗口iframe的window引用与名字 messenger.addTarget(iframe1.contentWindow, 'iframe1'); // 父窗口中 - 可以添加多个消息对象 messenger.addTarget(iframe2.contentWindow, 'iframe2'); ``` (5) 发消息时,要指定messenger的名字和消息,例如父窗体要给子窗体发消息: ```js // 父窗口中 - 向单个iframe发消息 messenger.targets['iframe1'].send(msg1); messenger.targets['iframe2'].send(msg2); // 父窗口中 - 向所有目标iframe广播消息 messenger.send(msg); ``` # 2.实例 基于上面的介绍,下面要实现开篇提出的需求了(实例代码只是示例如何传递数据,没有更改父窗体url)。这里分别是父窗体和子窗体的代码实现,可直接在浏览器中打开查看效果,其中messenger.js可以在这里[下载](https://github.com/biqing/MessengerJS/blob/master/messenger.js),放到项目目录下。 父窗体: ```js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>父窗体</title> <style type="text/css"></style> <!-- 这个messenger.js可下载放到项目目录下 --> <script type="text/javascript" src="./messenger.js"></script> </head> <body> <div>这是父窗体</div> <div id="msg"></div> <iframe id="iframe1" name="iframe1" src="./child.html" width="600px" height="316px" style="z-index: 100000;position: absolute;"> </iframe> </body> <script type="text/javascript"> //父页面中,注册一个messager到一个统一的项目中,第一个参数为自己页面的名称,第二个参数为项目名称 var messenger = new Messenger('parent', 'monitor'), iframe1 = document.getElementById('iframe1'); //父页面中绑定监听消息事件,当接受到iframe1发来的消息后执行 messenger.listen(function (msg) { // alert(msg); var oDiv = document.getElementById("msg"); oDiv.innerHTML += msg; //todo }); </script> </html> ``` 子窗体: ```js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>子窗体</title> <style type="text/css"></style> <!-- 这个messenger.js可下载放到项目目录下 --> <script type="text/javascript" src="./messenger.js"></script> </head> <body> <div style="background: #8CB08B;height:300px;"> <div>这是子窗体</div> <input type="button" onclick="sendMessage('这是一条来自子窗体的消息!')" value="按钮" /> </div> </body> <script type="text/javascript"> //子页面中,注册一个messager到一个统一的项目中,第一个参数为自己页面的名称,第二个参数为项目名称 var messenger = new Messenger('iframe1', 'monitor'); //添加消息对象, 明确告诉子窗口iframe的window引用与名字 messenger.addTarget(window.parent, "parent"); function sendMessage(msg) { messenger.targets["parent"].send(msg); } </script> </html> ``` 代码解释: 父窗体中嵌入iframe,要先引入messenger.js,同时初始化messenger到一个统一的项目中,其中第一个参数为自己页面messenger对象的名字,第二个参数为项目名称;然后父窗体要绑定监听消息事件,当接收到iframe子窗体发来的消息后执行。 子窗体也要先引入messenger.js,同时初始化一个messenger到一个统一的项目中,其中第一个参数为自己页面messenger对象的名字,第二个参数为项目名称;然后添加消息对象,告知子窗体的window引用与messenger对象的名字。然后在触发onclick事件时,向父窗口传递消息。发消息时,要指定接收消息的父窗体的messenger的名字,以及传递的消息。 # 3.小结 本文主要是介绍了一个MessengerJS方案及其使用方法,来解决父窗体与子窗体的通信问题。同时提供了一个完整的实例,可以实现子窗体向父窗体传递消息,父窗体通过监听消息事件,来获取子窗体消息的目的。如有问题,欢迎指正。 >**相关阅读** >[【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识](https://cloud.tencent.com/developer/edu/course-1128?fromSource=waitui) **此文已由作者授权腾讯云+社区发布,更多原文请[点击](https://cloud.tencent.com/developer/article/1361963?fromSource=waitui )** **搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!** 海量技术实践经验,尽在[云加社区](https://cloud.tencent.com/developer?fromSource=waitui)!

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

933 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传