主頁面、iframe之間的調用和傳值,無非就是兩個交互形式:
- 主頁面與子頁面的交互
- 子頁面之間的交互
接下來要講的是四種交互傳值的方式:利用postMessage方法傳值、DOM操作傳值、URL方式傳值、利用全局屬性傳值
利用postMessage方法傳值
這種方式非常像事件綁定、監聽。postMessage方法接收兩個參數:一條消息、一個表示消息接收方來自哪個域的字符串。第二個參數對保障安全通信非常重要,可以防止瀏覽器把消息發送到不安全的地方。
demo:
/*主頁面發送消息,子頁面接收消息的情況*/ //主頁面發送消息 var myFrame = document.getElementById("myFrame");//獲取框架 myFrame.contentWindow.postMessage("message", "http://crm.piao.qunar.com:8080"); //子頁面接收消息,並且做出回應 window.addEventListener('message', function(e){ if(e.origin == "http://crm.piao.qunar.com:8080") { console.log(e.data);//可以對數據進行處理 e.source.postMessage("確認收到消息", "http://crm.piao.qunar.com:8080"); } }); /*子頁面發送消息,主頁面接收消息的情況*/ //子頁面發送消息 parent.contentWindow.postMessage("message", "http://crm.piao.qunar.com:8080"); //主頁面接收消息 window.addEventListener('message', function(e){ if(e.origin == "http://crm.piao.qunar.com:8080") { console.log(e.data);//可以對數據進行處理 e.source.postMessage("確認收到消息", "http://crm.piao.qunar.com:8080"); } });
注意:
- postMessage()的第一個參數最早是作為“永遠都是字符串”來實現的。但后來這個參數的定義改了,改成允許傳入任何數據結構。可是,並非所有瀏覽器都實現了這一變化。為保險起見,使用postMessage()時,最好還是只傳字符串。如果你想傳入結構化的數據,最佳選擇是先在要傳入的數據上調用JSON.stringify(),通過postMessage()傳入得到的字符串,然后再在onmessage事件處理程序中調用JSON.parse()。
- e.source大多數情況下只是window對象的代理,並非實際的window對象。換句話說,不能通過這個代理對象訪問window對象的其他任何信息。
- 使用postMessage可能存在兼容性的問題
DOM操作傳值
iframe有contentWindow屬性,通過contentWindow屬性可以對iframe里面的DOM進行操作實現信息交互。還有幾個特殊的屬性top(最頂層框架)、parent(父級框架)、self(window自身)。
demo:
//子頁面操作父頁面 top.document.getElementById("mainElement").remove(); //父頁面操作子頁面 document.getElementById("subFrame").contentWindow.document.getElementById("subElement"); //子頁面一操作子頁面二 top.document.getElementById("subFrame2").contentWindow.document.getElementById("subElement2"); //子頁面二操作子頁面一 top.document.getElementById("subFrame1").contentWindow.document.getElementById("subElement1");
URL方式傳值
通過在URL上添加數據,然后解析URL,得到相應數據;不過這種方式只能是子頁面在加載時,父頁面向子頁面傳輸信息。
注意:在URL上添加一些特殊參數時,記得使用encodeURIComponent方法對其進行編碼
利用全局屬性傳值
直接在top、parent等全局變量中添加屬性,然后無論是哪個框架都可以通過全局性的屬性,取到其值
文件的共用性
主頁面與子頁面、子頁面與子頁面之間的JS、CSS文件都是不能通用的,也就是不同框架的JS、CSS在未做特殊處理的情況下,不能相互使用。