一、前言:
在web中,為了豐富我們的內容,往往需要引用其它HTML文件,這時候就需要用到 iframe 標簽,本文就主要記錄一下使用iframe所需要注意的問題
iframe 所使用的環境(筆者所遇到的)
1. web代碼兼容 PC端 和 移動端,這時候就想在移動端時把頁面限制在固定的寬高范圍中,於是就使用 iframe 把 相關頁面限制在其中
2. web引用別人的 HTML 內容,就使用iframe 來實現
二、遇到的問題:
1. 如何判斷當前是否在iframe中
// 1
if (self.frameElement && self.frameElement.tagName == "IFRAME") { alert('在iframe中'); } // 2
if (window.frames.length != parent.frames.length) { alert('在iframe中'); } // 3
if (self != top) { alert('在iframe中'); }
說明:
- 三種方式都是根據當前的窗口層級進行判斷,
- 以上是針對有 <frameset> 或者 <iframe> 的頁面,
- self.frameElement 可以獲取到當前的 iframe 節點(如果有的話),否則為null
解釋:window、top、parent、self 之間的聯系和區別
- window : 當前窗口
- top: 頂層窗口,針對有很多層的iframe
- parent: 父級窗口,即當前窗口的上一層窗口
- self: 當前窗口,和window、window.self 等價
2. iframe 和 它的父窗口如何通信
注意有兩種情況:
- iframe 和 父窗口 同源(即不會跨域,相同域名下),可以直接使用 節點 或 window 調用
- iframe 獲取父窗口節點:parent.window.document.getElementById("parentNode")
- iframe 調用父窗口方法:parent.parentFunc();
- 父窗口獲取 iframe節點:iframeObj.contentWindow.document.getElementById("childNode")
-
-
- this.myFrame表示 iframe對象
-
var obj=document.getElementsByTagName("iframe")[0].contentWindow; var ifmObj=obj.document.getElementById("childNode");
父窗口調用 iframe方法:iframeObj.contentWindow.parentFunc()
-
var obj=document.getElementsByTagName("iframe")[0].contentWindow; obj.parentFunc();
-
- iframe 和 父窗口 跨域(一般是調用別人的HTML )
- 必須使用安全的 postMessage方式來進行通信
-
// 向父窗口傳值 window.parent.postMessage({code: 1, msg: '向父窗口傳值'},*); // 向iframe傳值 document.getElementsByTagName("iframe")[0].contentWindow.postMessage({code: 2, msg: '向iframe傳值'},*); // 接收傳值 window.addEventList('message', (e) => { try{ if (e.data type e.data ==='string' ) { console.log(e.data); } } catch (err) { console.log(err) } });
-
event.source
:發送消息的窗口,可以通過區分網址來接收消息 -
event.origin
: 消息發向的網址,同上 -
event.data
: 消息內容
-
說明:
otherWindow.postMessage(message,targetOrigin,[transfer]);
-
otherWindow: 其他窗口的一個引用,比如iframe的contentWindow屬性、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames;
-
message: 將要發送到其他window的數據,這個數據會自動被序列化,數據格式也不受限制,String字符串,對象(包括JSON)都可以;
-
targetOrigin: 通過窗口的origin屬性來指定哪些窗口能接收到消息事件,這個值可以是"*"(表示無限制),或者一個URI。在發送消息的時候,如果目標窗口的協議、主機地址或者端口這三個的任意一項不匹配targetOrigin提供的值,那么消息就不會被發送。如果你明確的知道消息應該發送到哪個窗口,那么請始終提供一個有確切值的targetOrigin,而不是*。不提供確切的目標將導致數據泄露到任何對數據感興趣的惡意站點。
-
transfer(可選): 是一串和message 同時傳遞的
Transferable
對象. 這些對象的所有權將被轉移給消息的接收方,而發送一方將不再保有所有權。
三、最后
具體請看MDN: window.postMessage