今天填了一个h5利用iframe嵌套页面传递消息的坑。
原iframe传递消息举例
js1.html页面:
<script>
window.onload=function(){
window.frames[0].postMessage('This is data','*');
}
</script>
<div>
<iframe id="child" src="./js2.html"></iframe>
</div>
js2.html页面:
<script>
window.addEventListener("message", function(e){
console.log(e);
}, false);
</script>
以上js1页面为父页面,postMessage为HTML5中新增的postMessage方法,postMessage可以实现跨文档消息传输。
window.frames 返回窗口中所框架或 <iframe>。frames.length可以查看有多少框架或 <iframe>,上面js1页面只有一个iframe标签所以frames.length=1,window.frames[0]选择的就是给js2页面传递消息。
消息传递给js2页面后,接收信息用window.addEventListener触发message事件就可以接收js1接收的信息,具体信息在e.data里面。
不过!
坑来了。
嵌入的页面不止一个iframe!页面里添加了360和QQ的插件,两个插件在页面里动态添加了N个iframe,造成了js冲突,js2页面没有收到消息。
例如:
js1.html页面:
<script>
window.onload=function(){
window.frames[0].postMessage('This is data','*');
}
</script>
<div>
<iframe id="child6" src="./js6.html"></iframe>
<iframe id="child" src="./js2.html"></iframe>
<iframe id="child5" src="./js5.html"></iframe>
<iframe id="child4" src="./js4.html"></iframe>
</div>
js2.html页面:
<script>
window.addEventListener("message", function(e){
console.log(e);
}, false);
</script>
以上,js4、js5、js6页面好比如为其他插件加载的iframe,我的js2一下就被顶的不知道加载到第几位去了,笨方法可以frames.length看看有几个框架,然后window.frames[N]一个个试,不过缺点是不稳定,兼容性太差了。那么上网查一下window.frames[N]其实是可以指定选择框架的。
给自己的iframe加一个ID,window.frames[ID]就能指定加载js2的iframe。
但是!!非IE内核下window.frames['child'].postMessage(“XXXX”),失败了!!!提示postMessage未定义!!!what f**k,什么鬼,这么皮。
打印一下 window.frames['child']就会发现,返回的是dom对象。。所以不会有postMessage方法,更改之后改为window.frames['child'].contentWindow,用contentWindow把iframe的信息专换成window对象,这样以后加载多少iframe都不怕了。
最终改进版即为:
js1.html页面:
<script>
window.onload=function(){
window.frames["child"].contentWindow.postMessage('This is data','*');//非IE内核
//window.frames["child"].postMessage('This is data','*');//IE内核
}
</script>
<div>
<iframe id="child6" src="./js6.html"></iframe>
<iframe id="child" src="./js2.html"></iframe>
<iframe id="child5" src="./js5.html"></iframe>
<iframe id="child4" src="./js4.html"></iframe>
</div>
js2.html页面:
<script>
window.addEventListener("message", function(e){
console.log(e);
}, false);
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。