前幾天,舍友去某互聯網公司面前端研發工程師。回來後,他就跟我們聊了下麵試官給他出的題。其中,有一道題是“如何實現iframe高度的自適應?”。好吧,我承認,我聽到iframe這個詞的第一反應就是:這個東西性能差、搜索引擎不友好等等。由於這樣的偏見,還真沒有好好研究一下iframe。其實,iframe ...
前幾天,舍友去某互聯網公司面前端研發工程師。回來後,他就跟我們聊了下麵試官給他出的題。其中,有一道題是“如何實現iframe高度的自適應?”。好吧,我承認,我聽到iframe這個詞的第一反應就是:這個東西性能差、搜索引擎不友好等等。由於這樣的偏見,還真沒有好好研究一下iframe。其實,iframe對於第三方的廣告插入還是非常有用的。這兩天,好好研究了下iframe自適應的問題。研究的過程中,利用nodejs搭建了簡單的伺服器來測試方法的正確性。
同域下的iframe自適應
同域下實現iframe自適應比較簡單,可以直接利用javascript操作DOM來達到目的。下麵的示例是在http://localhost:8887作用域下,iframe.html引入index.html。
index.html
1 |
< img src = "ghost.png" alt = "ghost" style = "width:600px; height: 300px;" >
|
iframe.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
< iframe id = "iframe" src = "index.html" frameborder = "0" scrolling = "no" style = "border: 0px;" ></ iframe >
< script >
// 相容性代碼
function autoHeight(iframe) {
if (iframe) {
var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
if (iframeWin.document.body) {
iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
iframe.width = iframeWin.document.documentElement.scrollWidth || iframeWin.document.body.scrollWidth;
}
}
}
window.onload = function() {
autoHeight(document.getElementById('iframe'));
}
</ script >
|
顯示效果
註意:一定要通過伺服器來訪問iframe.html,像chrome這樣的瀏覽器訪問本地靜態文件會有限制,導致錯誤!
跨域下的iframe自適應
跨域(只要協議、功能變數名稱、埠有任何一個不同,都被當作是不同的域)的時候,由於js的同源策略,父頁面內的js不能獲取到iframe頁面的大小。
解決方案原理:使用代理頁面,並通過location.hash來進行傳值。
示例如下:http://localhost:8887下的一個頁面a.html使用iframe標簽引入http://localhost:8888下的一個頁面b.html。在http://localhost:8887下創建一個agent.html頁面做代理,b.html此時可利用隱藏的iframe通過location.hash將自己的大小傳給agent.html。由於agent.html與a.html在同一個域下,所以agent.html可直接操作a.html,不受js同源限制。
a.html
1 2 |
// 引入b.html
< iframe id = "a_iframe" src = "http://localhost:8888/b.html" frameborder = "0" scrolling = "no" style = "border: 0;" ></ iframe >
|
b.html
1 2 3 4 5 6 7 8 9 10 11 12 13 |
< img src = "ghost.png" alt = "ghost" style = "width:600px; height: 300px;" >
// 通過隱藏的iframe,利用loacation.hash傳值
< iframe id = "b_iframe" src = "http://localhost:8887/agent.html" height = "0" width = "0" frameborder = "0" style = "display: none;" ></ iframe >
< script >
(function autoHeight() {
var width = Math.max(document.body.scrollWidth, document.body.clientWidth);
var height = Math.max(document.body.scrollHeight, document.body.clientHeight);
var b_iframe = document.getElementById("b_iframe");
b_iframe.src = b_iframe.src + "#" + width + "|" + height;
})();
</ script >
|
agent.html
1 2 3 4 5 6 7 8 9 10 |
< script >
var a_iframe = window.parent.parent.document.getElementById("a_iframe");
var hash_url = window.location.hash;
if (hash_url.indexOf("#") >= 0) {
var hash_width = hash_url.split("#")[1].split("|")[0] + "px";
var hash_height = hash_url.split("#")[1].split("|")[1] + "px";
a_iframe.style.width = hash_width;
a_iframe.style.height = hash_height;
}
</ script >
|
顯示效果