為什麼是三談
為什麼是三談呢?一是因為這真的是一個被說爛的話題,二是因為太師傅在n年前就寫過這篇再談iframe自適應高度。之所以再提該問題,是因為之前專案中確實遇到了這個問題的方方面面,有必要總結一下。希望對各位有幫助,有錯誤請指正。
同域、子頁面高度不會動態增加
這種情況最簡單,直接透過腳本取得字頁面實際高度,修改iframe元素高度即可。但有二點必須注意:
如果頁面內有絕對定位或沒有清浮動的元素,情況有些複雜,不同瀏覽器處理結果不同,甚至包含Webkit核心的瀏覽器,具體請看這個Demo 。所以你要嘛進行瀏覽器偵測,要嘛用Math.max計算一個最大值,要嘛你想別的方法。
iframe所包含頁面可能非常大,需要很長的載入時間,為此直接計算高度的時候,很可能頁面還沒下載完,高度計算就會有問題。所以最好在iframe的onload事件中計算高度。這裡也要注意的是,IE下必須使用微軟事件模型obj.attachEvent來綁定onload事件。而別的瀏覽器直接obj.onload = function(){}也可以。
(function(){
var _reSetIframe = function(){
var frame = document.getElementById("frame_content_parent")
try {
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max
(frameContent.body.scrollHeight,
frameContent.documentElement.scrollHeight);
if (bodyHeight != frame.height){
frame.height = bodyHeight;
}
}
catch(ex) {
frame.height = 1800;
}
}
if(frame.addEventListener){
frame.addEventListener
("load",function(){setInterval(_reSetIframe,200);},false);
}else{
frame.attachEvent("onload",function(){setInterval(_reSetIframe,200);});
}
})();
同域、子頁面高度會動態增加、腳本可能完全失效
在第二個例子中,考慮到了腳本出錯的情況,但是萬一腳本根本不執行了呢,那iframe中的內容就會因為iframe的高度不夠而顯示不了。為此我們通常事先設定一個足夠的高度,為了前端控制方便,我覺得寫在CSS檔案中比較合適,需要修改時才改CSS就行了。這裡我設定了selector{ height:1800px; }。要注意的是,寫在樣式表裡的樣式,不能直接用node.style[property]來取,對於微軟模型,要用node.currentStyle[property](題外話:悲劇的IE模型不支援CSS偽類),對於W3C模型,要用window.getComputedStyle(node,null)[property]來取。我這裡圖方便直接用了YUI。
這裡又有一個問題,設定iframe的高度大於其包含頁面的高度時,各個瀏覽器的處理不一樣。例如在Firefox下,必須計算body元素的高度,而html元素的高度等於iframe的高度,然而當恰巧這個頁面又有絕對定位、未清浮動元素時,又不能透過body元素來取,顯然第一種方法缺點更小一些。具體請看這個Demo 。