深入 Iframe 自适应高度

DOCTYPE(CSS1Compat): HTML5, HTML4.01 Strict, HTML4.01 Transitional, XHTML1.0 Frameset, XHTML1.0 Strict, XHTML1.0 Transitional, XHTML1.1.

browser documentElement body
scrollHeight offsetHeight scrollHeight offsetHeight
IE ×
FF
Chrome
Safari
Opera

non-doctype(BackCompat): 无 DOCTYPE, IE: DOCTYPE 前有非空白字符(包括注释)。

browser documentElement body
scrollHeight offsetHeight scrollHeight offsetHeight
IE8 × × ×
FF5
Chrome13
Safari5
Opera11.50 ×

测试环境:Windows Server 2003.

综上所述:使用 document.body.scrollHeight 是最合适的。

计算高度的时机

父窗口检测子窗口:

iframe[onload=handler]

1
2
3

本窗口自检测:

dom-ready = handler;
window.onload = handler;
body[onload=handler]
1
2
3

子窗口获取自身在父窗口的 iframe 元素

如果父窗口有名字的话,可以直接通过 frames[name] 直接引用。

// 求教更恰当的命名。
function getParentFrame(){
  if(parent == window){return null;}
  if(window.name){return parent.frames[window.name];}
  var ifr = parent.document.getElementsByTagName("iframe");
  for(var i=0,l=ifr.length; i<l; i++){
    if(window == ifr[i].contentWindow){
      return ifr[i];
    }
  }
  var ifr = parent.document.getElementsByTagName("frame");
  for(var i=0,l=ifr.length; i<l; i++){
    if(window == ifr[i].contentWindow){
      return ifr[i];
    }
  }
  return null;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

其他相关

上面的 getParentFrame 通过窗口名字直接取得元素本身,这里要注意的一点, 以前写代码的时候有这样的代码定义:

function(){
  var elem = "elem",
      name = "name",
      desc = "desc";
}
1
2
3
4
5

后来要增加一个变量,但是不小心写错标点符号。

  function(){
      var elem = "elem",
+         id = elem.id;
          name = "name",
          desc = "desc";
  }
1
2
3
4
5
6

然后 name 就成了全局变量,无意中修改了 window.name 的值。 所以如果使用 name 作为局部变量的时候,千万要小心,否则执行这段代码之后, a[target=oldName] 的链接会因为找不到 frames[oldName] 而弹出新窗口。

延伸阅读

Help
[count]gg 跳转到第 [count] 行,默认第 1 行。
[count]G 跳转到第 [count] 行,默认最后一行。
[count]j 向下跳转 [count] 行,默认跳转一行。
[count]k 向上跳转 [count] 行,默认跳转一行。
/ 开始搜索。按 <Esc> 退出。
gh 跳转到首页。
gb 跳转到博客首页。
gw 跳转到 Wiki 首页。
gt 跳转到我的 Twitter Profile 页。
gp 跳转到我的 Github Profile 页。
? 打开帮助。按 <Esc> 退出。