今天填了一个h5利用iframe嵌套页面传递消息的坑。html
原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页面:dom
<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里面。post
不过!
坑来了。
嵌入的页面不止一个iframe!页面里添加了360和QQ的插件,两个插件在页面里动态添加了N个iframe,形成了js冲突,js2页面没有收到消息。插件
例如:
js1.html页面:code
<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页面:htm
<script> window.addEventListener("message", function(e){ console.log(e); }, false); </script>
以上,js四、js五、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,什么鬼,这么皮。ip
打印一下 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>