计算跨浏览器的iframe高度

时间:2008-10-16 07:54:39

标签: javascript jquery iframe

我的javascript体验中最困难的问题之一是 iframe高度的正确(即“跨浏览器”)计算。 在我的应用程序中,我有很多动态生成的iframe,我希望它们都在load事件结束时做一些autoresize来调整它们的高度和宽度。

高度计算的情况下,我的最佳解决方案如下(在jQuery的帮助下):

function getDocumentHeight(doc) {
  var mdoc = doc || document;
  if (mdoc.compatMode=='CSS1Compat') {       
      return mdoc.body.offsetHeight;
  }
  else {
    if ($.browser.msie)
      return mdoc.body.scrollHeight;
    else  
      return Math.max($(mdoc).height(), $(mdoc.body).height());
  }
}

我没有成功搜索互联网。我还测试了雅虎库,它有一些文档和视口尺寸的方法,但它并不令人满意。 我的解决方案工作正常,但有时它会计算出更高的高度。 我已经在Firefox / IE / Safari中研究并测试了大量有关文档高度的属性:documentElement.clientHeight, documentElement.offsetHeight, documentElement.scrollHeight, body.offsetHeight, body.scrollHeight, ... 此外,jQuery在调用$(document.body).height(), $('html', doc).height(), $(window).height()

的各种浏览器中没有连贯的行为

我不仅在load事件结束时调用上面的函数,而且在动态插入DOM元素或隐藏或显示的元素的情况下调用上述函数。这种情况有时会破坏仅在load事件中起作用的代码。

有人拥有真正的跨浏览器(至少是Firefox / IE / Safari)解决方案吗?一些提示或提示?

6 个答案:

答案 0 :(得分:4)

虽然我喜欢你的解决方案,但我总是发现IFRAME比它们的价值更麻烦。

为什么? 1.尺寸问题。 2. iframe有src属性需要担心。即绝对路径。 3.页面的额外复杂性。

我的解决方案 - 通过AJAX调用动态加载的DIV。 DIV将自动调整大小。虽然AJAX代码需要javascript工作(可以通过框架完成),但它们与网站的位置有关。 3是一个洗,你交易的页面复杂到javascript。

而不是< IFRAME ...>使用< DIV id =“mystuff”/>

执行ajax调用以使用数据填充mystuff div并让浏览器担心它。

答案 1 :(得分:2)

这一段时间以来一直没有得到公认的答案,所以我想在经过一些研究后提供最终结果的解决方案。 这是跨浏览器和跨域名(例如,当iframe指向来自其他域的内容时)

我最终使用包含在jQuery pluging中的html5的消息传递机制,使其与使用各种方法的旧浏览器兼容(其中一些在此线程中描述)。

最终解决方案非常简单。

在主持人(父)页面上:

// executes when a message is received from the iframe, to adjust 
// the iframe's height
    $.receiveMessage(
        function( event ){
            $( 'my_iframe' ).css({
                height: event.data
            });
    });

// Please note this function could also verify event.origin and other security-related checks.

在iframe页面上:

$(function(){

    // Sends a message to the parent window to tell it the height of the 
    // iframe's body

    var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);

    $.postMessage(
        $('body').outerHeight( true ) + 'px',
        '*',
        target
    );

});

我在XP和W7上的Chrome 13 +,Firefox 3.6 +,IE7,8和9上进行了测试,在OSX和W7上进行了测试。 ;)

答案 2 :(得分:1)

因为在你的例子中你正在访问里面的文件,所以我想你正在谈论知道文件的高度而不是框架本身。此外,这意味着内容来自您自己的网站,您可以控制它的内容。

那么,为什么不简单地在你的内容周围放置一个DIV,然后使用那个DIV的clientHeight?

您在IFRAME中加载的代码:

...
<body>
  <div id="content">
  ...
  </div>
</body>

父文件:

 function getDocumentHeight(mdoc) {
    return mdoc.getElementById("content").clientHeight;
 }
顺便说一下,你的示例函数的这一部分没有意义,因为“document”没有引用IFRAME: var mdoc = doc || document;

答案 3 :(得分:0)

这是一个似乎有效的解决方案。基本上,在大多数情况下,scrollHeight是正确的值。但是,在IE(特别是6和7)中,如果内容仅包含在文本节点中,则不计算高度,只是默认为CSS中设置的高度或iframe上的“height”属性。这是通过反复试验找到的,所以请把它当作值得的。

function getDocumentHeight(doc) {
  var mdoc = doc || document; 
  var docHeight = mdoc.body.scrollHeight;

  if ($.browser.msie) {
      // IE 6/7 don't report body height correctly.  
      // Instead, insert a temporary div containing the contents.

      var child = $("<div>" + mdoc.body.innerHTML + "</div>", mdoc);
      $("body", mdoc).prepend(child);
      docHeight = child.height();
      child.remove();
  }

  return docHeight;
}

答案 4 :(得分:0)

我发现这个解决方案适用于6 +,ff 3.5 +,safari 4+。我正在创建并向文档追加iframe。在执行了一些其他dom操作之后,在jQuery的load事件结束时执行以下代码。由于在load事件中发生了额外的dom操作,因此我需要超时。

// sizing - slight delay for good scrollheight
setTimeout(function() {
   var intContentHeight = objContentDoc.body.scrollHeight;
   var $wrap = $("#divContentWrapper", objContentFrameDoc);
   var intMaxHeight = getMaxLayeredContentHeight($wrap);
   $this.height(intContentHeight > intMaxHeight ? intMaxHeight : intContentHeight);

   // animate
   fireLayeredContentAnimation($wrap);
}, 100);

我需要考虑一些大小调整限制,这就是getMaxLayeredContentHeight调用为我检查的内容。希望有所帮助。

答案 5 :(得分:0)

Here's a script根据身高的高度来调整iFrame的大小。