今天填了一個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>