我正在加载一个iframe中的aspx网页。Iframe中的内容的高度可以大于Iframe的高度。iframe不应该有滚动条。

我在iframe里面有一个包装器div标签,基本上是所有的内容。我写了一些jQuery来实现调整大小:

$("#TB_window", window.parent.document).height($("body").height() + 50);

在哪里 TB_window是包含Iframe的div。

Body - iframe中aspx的Body标签。

该脚本附加到iframe内容。我从父页面获得TB_window元素。虽然这在Chrome上工作得很好,但在Firefox中TB_window崩溃了。我真的不明白为什么会发生这种情况。


当前回答

其他答案不适合我,所以我做了一些改变。希望这能有所帮助

$('#iframe').on("load", function() {
    var iframe = $(window.top.document).find("#iframe");
    iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});

其他回答

你也可以添加一个重复的requestAnimationFrame到你的resizeIframe(例如来自@BlueFish的答案),它总是在浏览器绘制布局之前被调用,你可以更新iframe的高度,当它的内容已经改变了它们的高度。例如,输入表单,惰性加载内容等。

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    window.requestAnimationFrame(() => resizeIframe(iframe));
  }
</script>  

<iframe onload="resizeIframe(this)" ...

你的回调应该足够快,对你的整体性能没有太大的影响

我发现接受的答案是不够的,因为X-FRAME-OPTIONS: Allow-From在safari或chrome中不支持。相反,我们采用了不同的方法,这可以从Disqus的Ben Vinegar的演讲中找到。其思想是在父窗口中添加一个事件侦听器,然后在iframe中使用窗口。postMessage发送一个事件给父进程,告诉它做一些事情(调整iframe的大小)。

所以在父文档中,添加一个事件监听器:

window.addEventListener('message', function(e) {
  var $iframe = jQuery("#myIframe");
  var eventName = e.data[0];
  var data = e.data[1];
  switch(eventName) {
    case 'setHeight':
      $iframe.height(data);
      break;
  }
}, false);

在iframe中,写一个函数来发布消息:

function resize() {
  var height = document.getElementsByTagName("html")[0].scrollHeight;
  window.parent.postMessage(["setHeight", height], "*"); 
}

最后,在iframe中,给body标签添加一个onLoad来触发resize函数:

<body onLoad="resize();">

您可以通过使用以下方法检索IFRAME内容的高度: contentWindow.document.body.scrollHeight

加载IFRAME后,您可以通过以下操作更改高度:

<script type="text/javascript">
  function iframeLoaded() {
      var iFrameID = document.getElementById('idIframe');
      if(iFrameID) {
            // here you can make the height, I delete it first, then I make it again
            iFrameID.height = "";
            iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
      }   
  }
</script>   

然后,在IFRAME标记上,像这样连接处理程序:

<iframe id="idIframe" onload="iframeLoaded()" ...

我有一个情况在一段时间前,我还需要调用iframeLoaded从IFRAME本身的表单提交后发生。您可以通过在IFRAME的内容脚本中执行以下操作来实现这一点:

parent.iframeLoaded();
$(document).height() // - $('body').offset().top

和/或

$(window).height()

参见Stack Overflow问题如何获取body元素的高度。

试着用jQuery找到身体的高度:

if $("body").height()

它没有值,如果Firebug。也许这就是问题所在。

对阿里斯托斯的回答略有改进…

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
  }
</script>  

然后在iframe中如下声明:

<iframe onload="resizeIframe(this)" ...

有两个小的改进:

您不需要通过document获取元素。getElementById——因为你已经在onload回调中有它了。 不需要设置iframe。Height = ""如果你要在下一个语句中重新赋值。这样做实际上会在处理DOM元素时引起开销。

编辑: 如果帧中的内容总是在变化,那么调用:

parent.resizeIframe(this.frameElement); 

从更新后的iframe内。适用于同一产地。

或自动检测:

  // on resize
  this.container = this.frameElement.contentWindow.document.body;

  this.watch = () => {
    cancelAnimationFrame(this.watcher);

    if (this.lastScrollHeight !== container.scrollHeight) {
      parent.resizeIframeToContentSize(this.frameElement);  
    }
    this.lastScrollHeight = container.scrollHeight;
    this.watcher = requestAnimationFrame(this.watch);
  };
  this.watcher = window.requestAnimationFrame(this.watch);