根据内部内容使 iframe 高度动态化 - JQUERY/Javascript

IT技术 javascript jquery asp.net iframe
2021-01-23 00:50:56

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

div在 iframe 中有一个包装标签,它基本上是所有内容。我写了一些 jQuery 来调整大小:

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

TB_window包含 的 div 在哪里 Iframe

body - iframe 中 aspx 的 body 标签。

此脚本附加到 iframe 内容。我正在TB_window从父页面获取元素。虽然这在 Chrome 上运行良好,但 TB_window 在 Firefox 中崩溃。我真的很困惑/迷失了为什么会发生这种情况。

6个回答

您可以使用以下方法检索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()" ...

不久前我遇到了一种情况,在其中发生表单提交后,我还需要iframeLoadedIFRAME自身调用您可以通过在IFRAME的内容脚本中执行以下操作来实现这一点

parent.iframeLoaded();
这解决了跨域 iframe 大小问题github.com/davidjbradshaw/iframe-resizer
2021-03-13 00:50:56
它不支持跨域。
2021-03-19 00:50:56
@Soumya 跨域与此代码无关。您可以使用命令绕过一个安全问题。
2021-03-26 00:50:56
@Soumya 查找X-FRAME-OPTIONS添加一行:Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");response.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
2021-03-31 00:50:56
@deebs 您也可以尝试更改iFrameID.height = "";iFrameID.height = "20px";. 默认浏览器 iframe 高度是 150 像素,这是将其""重置回的值。
2021-04-08 00:50:56

对阿里斯托斯的稍微改进的答案......

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

然后在您的 iframe 中声明如下:

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

有两个小的改进:

  1. 您不需要通过 document.getElementById 获取元素 - 因为您已经在 onload 回调中拥有它。
  2. 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);
这个想法是计算新的高度并向需要接收消息的父框架发送消息并相应地调整 iframe 的高度。
2021-03-12 00:50:56
如果框架中的内容总是在变化,你会怎么做?
2021-03-16 00:50:56
如果内容大小不断变化和/或如果您的 iframe 被设计为位于 iframe 从中拉出页面的域以外的其他域,那么您将需要做一些不同的事情。
2021-03-26 00:50:56
对我来说总是一些像素的短,所以我想出了这个: function resizeIframe(iframe) { var size=iframe.contentWindow.document.body.scrollHeight; var size_new=size+20; iframe.height = size_new + "px"; }
2021-03-31 00:50:56
为此......解决方案是使用postMessage和receiveMessage。我使用github.com/jeffomatic/nojquery-postmessage解决了这个问题
2021-04-04 00:50:56

我发现接受的答案还不够,因为safari 或 chrome 不支持X-FRAME-OPTIONS: Allow-From 而是采用了不同的方法,在Disqus 的 Ben Vinegar演示文稿中找到这个想法是向父窗口添加一个事件侦听器,然后在 iframe 内部,使用 window.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 以触发调整大小函数:

<body onLoad="resize();">
伟大的!但它只加载一次高度。如果您想让 iframe 真正响应,我更喜欢每秒调用 resize 方法,如下所示:setInterval(resize, 1000);
2021-03-12 00:50:56
为了让它对我有用,我不得不将“window.parent”更改为“parent”。
2021-03-15 00:50:56

将此添加到 iframe,这对我有用:

onload="this.height=this.contentWindow.document.body.scrollHeight;"

如果您使用 jQuery,请尝试以下代码:

onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"

您可以查看四种不同的属性来获取 iFrame 中内容的高度。

document.documentElement.scrollHeight
document.documentElement.offsetHeight
document.body.scrollHeight
document.body.offsetHeight

可悲的是,他们都可以给出不同的答案,而且这些在浏览器之间是不一致的。如果您将正文边距设置为 0,则document.body.offsetHeight给出了最佳答案。要获得正确的值,请尝试此功能;它取自iframe-resizer库,该库还负责在内容更改或调整浏览器大小时保持 iFrame 的正确大小。

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        function getPixelValue(value) {
            var PIXEL = /^\d+(px)?$/i;

            if (PIXEL.test(value)) {
                return parseInt(value,base);
            }

            var 
                style = el.style.left,
                runtimeStyle = el.runtimeStyle.left;

            el.runtimeStyle.left = el.currentStyle.left;
            el.style.left = value || 0;
            value = el.style.pixelLeft;
            el.style.left = style;
            el.runtimeStyle.left = runtimeStyle;

            return value;
        }

        var 
            el = document.body,
            retVal = 0;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            retVal =  document.defaultView.getComputedStyle(el, null)[prop];
        } else {//IE8 & below
            retVal =  getPixelValue(el.currentStyle[prop]);
        } 

        return parseInt(retVal,10);
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}
这不适用于“卷起”的项目,例如数据表或浮动 div。高度基于正常展开的高度,而不是最终高度。
2021-04-07 00:50:56
@djack109 很可能您的 CSS 中的某些内容会阻止页面上的元素缩小
2021-04-08 00:50:56