一直有个认知就是最好不要用iframe,这么多年也没用过几次。最近一个项目因为一些原因需要用到这个,而且需要实现父子页面间互相通信,这可难住宝宝了。好在办法总比困难多,最后用一种不友好的方式解决了。
背景:
需要实现的是一个类似[个人中心]里面弹出一个问卷,当用户答完要自动关闭弹窗。
因为这个问卷是后期加入的,所以另起了一个 Vue 项目,做的也是异常的复杂(下次再说吧),在服务器上也是放在不同的位置。
问题来了:因为弹窗是通过js动态加载上去的,而iframe里面的内容又在另一个位置。父页面无法知道子页面什么时候答完了,子页面也无法操作父页面直接关闭。
烂方法:
因为时间紧任务重,没有想到什么好方法,于是我就把弹窗的背景遮罩放在了父页面,当点击遮罩会提示是否退出答题,然后把答案做本地缓存,下次用户进入时再继续答题。
槽点就是当用户真的答完题了,我也这么提示,就显得一点不友好了,体验太差了。
认识iframe
iframe具有自己的属性和方法,主要如下:
frameborder 边框,默认为1,0表示无边框(设为0可以取消内部滚动条)
height/width 宽高,单位是px
marginheight/marginwidth 框架内容到框架的边距,单位是px
name 框架的名称
src 嵌套页面的URL地址
scrolling 是否允许滚动
获取iframe内部的内容:
contentWindow 访问iframe元素所包含的HTML页面的window对象
contentDocument 访问iframe元素所包含的HTML页面的document对象
window.frames[‘name’]window.parent 从框架中引用它的父框架的window
window.top 最顶级容器的window对象
防止自己的网页被别人当成iframe加载
|
大杀器:postMessage
记得是有这么个东西,但是一直没细看是怎么用的。抽出空来的时候看了下一个前辈写的教程 《html5 postMessage解决跨域、跨窗口消息传递》,讲解的很详细,还有非常好的demo,真是贴心。
试了一下,连360浏览器的兼容模式下[IE11]都可以正常关闭弹窗,棒棒哒。
postMessage是HTML5引入的一个API,可以实现跨域通信。
信息发送方
window.postMessage()方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个
MessageEvent
消息。window.postMessage(message,targetOrigin,[transfer]);
message:要发送到其他窗口的数据
targetOrigin:指定可以接收数据的源,如果是*表示无限制
transfer:是一个可选的参数,随message一起发送
信息接收方
window.addEventListener(“message”, receiveMessage, false);
message:必须是这个,不能改成别的
receiveMessage:接收数据的方法
安全问题
为了安全,在接收的时候要判断一下来源
双向通信
postMessage 支持双向通信,既支持父页面传给子页面,也支持子页面传给父页面
|
上代码:
子页面js
父页面js
|
message不能替换成其他参数,
e就是event,e.data——传递过来的数据,e. source——发送消息的窗口对象,e.origin——发送消息的源
总结
很简单啊,有木有。几行代码解决了大问题,体验更优雅,就酱。
参考: