雖然平時不怎么用iframe,但經常在網上聽一些前輩說iframe怎樣怎樣,今天索性對iframe來個大研究,那樣就不必去記那些條條框框了,自己體驗一遍比看什么都好。
創建兩個文件一個index.html和iframe.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h2>index.html</h2>
<iframe src="iframe.html"></iframe>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe</title>
<style>
h2{
color:red;
}
</style>
</head>
<body>
<h2>iframe.html</h2>
</body>
</html>
效果如圖

可以看到在iframe中,默認有一個邊框,並且更重要的是,我在iframe.html中設置的樣式並不會影響到index.html,也就是說它們之間的樣式是隔離的,這一點很重要。
在index.html中設置的樣式同樣也不會被應用到iframe.html中,如下圖

以上效果的代碼如下
index.html
h2{
color:green;
}
仔細看iframe中的內容,你會很奇怪,我們明明沒有設置iframe的寬高,iframe卻莫名奇妙的有個高度,如果我們將內容再增加一些,會出現一條滾動條,如下圖

出現滾動條倒是好解釋,因為iframe的高度不夠,所以就溢出了,但往往我們不希望出現滾動條,這樣的話,我們就得知道這個iframe中的內容有多高,然后將這個高度賦值給iframe。
通過審查元素來看看這個iframe中的內容有多高

雖然通過審查元素能夠知道iframe中的內容有多高,在項目中這樣去使用倒也不是不行,而是太low,既然這樣不行,那么我們就要通過javascript動態去計算了,最后將計算后的值賦給iframe高,那么我們究竟去計算誰的高度呢?iframe還是?來看下面這個動圖

看出來了嗎,這個高度是iframe中html的,也就是說只需要去計算html的高度,然后將html的高度賦給iframe即可。
正常情況下,我們通過document.documentElement.scrollHeight即可獲取到html的高度,但是在iframe中,這樣是不行的,因為iframe中的內容與外部是隔離的,iframe中的內容並不屬於當前頁面,也就是說我們無法使用document.documentElement這種方式來獲取html,而是需要通過iframe.contentDocument.documentElement這種方式來獲取html。iframe.contentDocument可以獲取到iframe中的document對象,因此我們只需要下面這樣設置,即可使用iframe自適應內容。
index.html
<iframe src="iframe.html" id="iframe" onload="this.height = this.contentDocument.documentElement.scrollHeight + 'px'"></iframe>
其中的this表示iframe本身,如果你需要大量使用這種方式,可以將以上代碼封裝成一個函數,注意我是在當iframe執行onload事件的時候才給iframe賦值的,因為如果iframe的內容沒有加載成功,我們是無法正確的獲取iframe中html的高度的,如果想執行自適應還得將iframe的寬設置成100%。
另外還可以使用iframe.contentWindow來獲取在iframe中的window對象。
雖然說可以通過javascript動態去改變iframe的高度,但需要注意一個問題,看下圖

看到上面這張圖你可能會很奇怪,為什么現在這個iframe又出現滾動條了呢,出來滾動條的原因就在於,我在iframe中加入了幾張圖片,而圖片的加載速度是比較慢的,而當iframe沒有加載成功之前,是不會執行onload事件的,因此自然就出來滾動條了,如果想解決這個問題我們需要在iframe中給body加上overflow:hidden;這段代碼。
使用iframe后,我們還需要注意得一個問題就是主頁面的onload事件包含了iframe的加載,也就是不僅本頁面要加載完畢iframe中的內容也要加載完畢,onload事件才會被觸發,如下動圖

從以上圖,我們可以看到當iframe加載完畢,主頁中的onload事件才被觸發的,其中代碼如下
index.html
<body onload="console.log('indexLoad ok')">
<h2>index.html</h2>
<iframe src="iframe.html" id="iframe" onload="this.height = this.contentDocument.documentElement.scrollHeight + 'px'"></iframe>
</body>
這也就是說,如果你只是想當主頁加載完畢就執行onload事件,那不好意思onload做不到,而如果你只是想將一些如公共的頭部之類的放在iframe中,那這是沒有問題的(不過最好還是建議你通過其他方式實現)。
另外一點就是主頁和iframe使用的是同一個線程,比如下面這段代碼
index.html
<h2>index.html</h2>
<iframe src="iframe.html"></iframe>
<script src="lib/jquery/1.10.2/jquery.js"></script>
<script>
console.log(3);
function imageCheckHttps(data){
console.log(data);
}
$.get("http://p.3.cn/prices/mgets?skuIds=J_954086&type=1",null,imageCheckHttps,"jsonp");
</script>
iframe.html
<h2>iframe.html</h2>
<script src="lib/jquery/1.10.2/jquery.js"></script>
<script>
console.log(1);
function imageCheckHttps(data){
console.log(data);
}
$.get("https://image.baidu.com/httpsjsonp/pc?callback=imageCheckHttps&_=1491228688850",null,imageCheckHttps,"jsonp");
$.get("https://image.baidu.com/httpsjsonp/pc?callback=imageCheckHttps&_=1491228688850",null,imageCheckHttps,"jsonp");
</script>
來看一下它的輸出結果

index.html中的console.log(3)並沒有在console.log(1)之前輸出,這也就證明了主頁和iframe使用的是同一個線程。
iframe在移動端中的問題
假如說你需要在移動端中使用移動事件,那就得注意了,你在主頁中加的移動事件,對iframe來說是無效的,如下動圖。

代碼如下
index.html
<h2>index.html</h2>
<iframe src="iframe.html" id="iframe"></iframe>
<script>
document.addEventListener("touchmove",function(event){
console.log(event);
});
</script>
從以上結果也可以猜想出,主頁中點擊事件中的event獲取到的參數跟iframe中獲取到的參數的相對點不是同一個東西。
因此在使用iframe的時候,還請慎重,當然具體還得看你選擇iframe的目的,而不是死記。
