采用JavaScript來控制iframe元素的高度是iframe高度自適應的關鍵,同時由於JavaScript對不同域名下權限的控制,引發出同域、跨域兩種情況。
由於客戶端js使用瀏覽器的同源安全策略,跨域情況下,被嵌套頁面如果想要獲取和修改父頁面的DOM屬性會出現權限不足的情況,提示錯誤:Permission denied to access property 'document'。這是因為除了包含腳本的文檔載入的主機外,同源策略禁止客戶端腳本鏈接到其他任何主機或者訪問其他任何主機的數據。這意味着訪問一個web服務的javascript代碼通常只有在它也駐留在Web服務本身所在的同一個服務器的時候才有用。
所以在跨域情況下,我們遇到的問題就是:父窗口無法獲得被嵌套頁面的高度,而且被嵌套頁面也無法通過駐留在其服務器上的js修改父窗口Dom節點的屬性。所以我們需要一個媒介,來獲得被嵌套頁面的高度同時又能修改主界面iframe節點的高度。
思路:現有主界面main在域a下,被嵌套頁面B在域b下,被嵌套頁面B又嵌套一個在域a下的中介頁面A。 當用戶打開瀏覽器訪問mail.html的時候載入B,觸發B的onload事件獲取其自身高度,然后B載入A,並將高度值作為參數賦值給A的location對象。這樣A就可以通過location.hash獲得B的高度。(location是javascript里邊管理地址欄的內置對象,比如location.href就管理頁面的url,用location.href=url就可以直接將頁面重定向url。而location.hash則可以用來獲取或設置頁面的標簽值。比如http://domain/#admin的location.hash="#admin"。利用這個屬性值可以做一些非常有意義的事情。)。由於A和main頁面同域,所以可以修改main的dom節點屬性,從而達到我們設置iframe標簽高度的目的。
關鍵代碼:
iframe主頁面:main.html
<iframe id="iframeB" name="iframeB" src="www.b.com/B.html" width="100%" height="auto" scrolling="no" frameborder="0"></iframe>
iframe嵌套頁面:B.html
<iframe id="iframeA" name="iframeA" src="" width="0" height="0" style="display:none;" ></iframe> <script type="text/javascript"> function sethash(){ hashH = document.documentElement.scrollHeight; //獲取自身高度 urlC = "www.a.com/A.html"; //設置iframeA的src document.getElementById("iframeA").src=urlC+"#"+hashH; //將高度作為參數傳遞 } window.onload=sethash; </script>
中介頁面:A.html
<script> function pseth() { var iObj = parent.parent.document.getElementById('iframeB');//A和main同域,所以可以訪問節點 iObjH = parent.parent.frames["iframeB"].frames["iframeA"].location.hash;//訪問自己的location對象獲取hash值 iObj.style.height = iObjH.split("#")[1]+"px";//操作dom } pseth(); </script>
同域情況下直接在被嵌套的頁面B中獲取其自身高度並操作其父窗口main的dom屬性即可。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <iframe src="http://www.a.com/" id="iframepage" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" width="100%" onload="iFrameHeight()"></iframe> </div> </form> <script type="text/javascript" language="javascript"> function iFrameHeight() { var subWeb = document.frames ? document.frames["iframepage"].document : ifm.contentDocument; if (ifm != null && subWeb != null) { ifm.height = subWeb.body.scrollHeight; ifm.width = subWeb.body.scrollWidth; } } </script> </body> </html>