深入 Iframe 自适应高度

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

| browser | documentElement | | body | | |\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n| | | scrollHeight | offsetHeight | scrollHeight | offsetHeight | | IE | √ | × | √ | √ | | FF | √ | √ | √ | √ | | Chrome | √ | √ | √ | √ | | Safari | √ | √ | √ | √ | | Opera | √ | √ | √ | √ |

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

| browser | documentElement | | body | | |\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n|\n\n\n\n\n\n\n\n\n\n\n\n\n\n| | | scrollHeight | offsetHeight | scrollHeight | offsetHeight | | IE8 | × | × | √ | × | | FF5 | √ | √ | √ | √ | | Chrome13 | √ | √ | √ | √ | | Safari5 | √ | √ | √ | √ | | Opera11.50 | √ | √ | √ | × |

测试环境:Windows Server 2003.

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

计算高度的时机

父窗口检测子窗口:

1iframe[onload=handler]

本窗口自检测:

1dom\nready = handler;
2window.onload = handler;
3body[onload=handler]

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

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

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

其他相关

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

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

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

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

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

延伸阅读

\n 再谈iframe自适应高度 \n 三谈Iframe自适应高度