根据里面的内容制作iframe高度动态 - JQUERY / Javascript

时间:2012-02-06 15:55:29

标签: javascript jquery asp.net iframe

我正在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上运行良好,但TB_window在Firefox中崩溃。我真的很困惑/失去了为什么会发生这种情况。

21 个答案:

答案 0 :(得分:195)

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

答案 1 :(得分:95)

对Aristos的回答略有改善......

<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元素。

答案 2 :(得分:51)

我发现接受的答案不够,因为X-FRAME-OPTIONS:Allow-From isn't supported in safari or chrome。用一种不同的方法代替,发现于来自Disqus的Ben Vinegar给出的presentation。想法是向父窗口添加一个事件监听器,然后在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中,将onLoad添加到body标签以触发resize函数:

<body onLoad="resize();">

答案 3 :(得分:6)

您可以查看四种不同的属性来获取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');
}

答案 4 :(得分:2)

以防这有助于任何人。我试着让我的头发工作,然后我注意到iframe有一个高度为100%的班级条目。当我删除它时,一切都按预期工作。所以,请检查是否有任何css冲突。

答案 5 :(得分:1)

您可以在此处引用相关问题 - How to make width and height of iframe same as its parent div?

设置动态高度 -

  1. 我们需要与跨域iFrames和父
  2. 进行通信
  3. 然后我们可以将iframe的滚动高度/内容高度发送到父窗口
  4. 代码 - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8

答案 6 :(得分:1)

我找到的最简单的方法是使用javscript / jquery而不是:

<iframe style="min-height:98vh" src="http://yourdomain.com" width="100%"></iframe>

此处1vh =浏览器窗口高度的1%。所以要设定的高度的理论值是100vh,但实际上98vh是神奇的。

答案 7 :(得分:0)

BlueFish的答案略有改善......

function resizeIframe(iframe) {
    var padding = 50;
    if (iframe.contentWindow.document.body.scrollHeight < (window.innerHeight - padding))
        iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    else
        iframe.height = (window.innerHeight - padding) + "px";
}

这需要考虑窗口屏幕(浏览器,手机)的高度,这对于响应式设计和具有巨大高度的iframe是有益的。 填充表示在iframe进入整个屏幕的情况下,iframe上方和下方的填充。

答案 8 :(得分:0)

在我的项目中有一个要求,我们在加载时制作动态屏幕,如仪表板对齐,它应该显示在整个页面上,并且如果用户正在最大化或调整浏览器窗口的大小,应该动态调整。 为此,我创建了 url 并使用 iframe 打开了用 cognos BI 编写的动态报告之一。在 jsp 中,我们必须嵌入 BI 报告。我已经使用 iframe 将此报告嵌入到 jsp 中。以下代码适用于我的情况。

<iframe src= ${cognosUrl} onload="this.style.height=(this.contentDocument.body.scrollHeight+30) +'px';" scrolling="no" style="width: 100%; min-height: 900px; border: none; overflow: hidden; height: 30px;"></iframe>

答案 9 :(得分:0)

所有其他答案都是正确的,但是如果 iframe 有一些动态内容,例如稍后加载并动态更改 iframe 滚动高度的地图,该怎么办。我就是这样实现的。

var iFrameID = document.getElementById('idIframe');

intval =  setInterval(function(){
if(iFrameID.scrollHeight == iFrameID.contentWindow.document.body.scrollHeight){
     clearInterval(intval);
}else{
   iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
  }
},500)

我只是将代码包装在 setInterval 中,它使 iframe 滚动高度与 iframe 内容滚动高度相匹配,然后清除间隔。

答案 10 :(得分:0)

我正在使用jQuery和下面的代码为我工作,

var iframe = $(window.top.document).find("#iframe_id_here");
iframe.height(iframe.contents().height()+'px' );

答案 11 :(得分:0)

只需确定iframe容器的位置:绝对,iframe就会根据其内容自动更改其高度

<style>
   .iframe-container {
       display: block;
       position: absolute;
       /*change position as you need*/
       bottom: 0;
       left: 0;
       right: 0;
       top: 0;
   }
   iframe {
       margin: 0;
       padding: 0;
       border: 0;
       width: 100%;
       background-color: #fff;
   }
 </style>
 <div class="iframe-container">
     <iframe src="http://iframesourcepage"></iframe>
 </div>

答案 12 :(得分:0)

使用PHP htmlspecialchars()进行样本+检查高度是否存在并且是否大于0:

$my_html_markup = ''; // Insert here HTML markup with CSS, JS... '<html><head></head><body>...</body></html>'
$iframe = '<iframe onload="if(this.contentWindow.document.body.scrollHeight) {this.height = this.contentWindow.document.body.scrollHeight;}" width="100%" src="javascript: \''. htmlspecialchars($my_html_markup) . '\'"></iframe>';

答案 13 :(得分:0)

其他答案对我不起作用,所以我做了一些更改。希望这会有所帮助

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

答案 14 :(得分:0)

您还可以在resizeIframe中添加一个重复的requestAnimationFrame(例如,从@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)" ...

您的回调应该足够快,不会对您的整体效果产生太大影响

答案 15 :(得分:0)

jQuery('.home_vidio_img1 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery(this).replaceWith(video);
});

jQuery('.home_vidio_img2 img').click(function(){
    video = <iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>;
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img3 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img4 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

答案 16 :(得分:0)

简单的解决方案是测量内容区域的宽度和高度,然后使用这些测量值来计算底部填充百分比。

在这种情况下,测量值为1680 x 720 px,因此底部的填充为720/1680 = 0.43 * 100,达到43%。

.canvas-container {    
    position: relative;
    padding-bottom: 43%; // (720 ÷ 1680 = 0.4286 = 43%)
    height: 0;
    overflow: hidden;   
}

.canvas-container iframe {    
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;   
}

答案 17 :(得分:0)

当您需要没有jquery的解决方案时,这个很有用。在这种情况下,您应该尝试添加容器并以百分比设置填充

HTML示例代码:

<div class="iframecontainer">
    <iframe scrolling="no" src="..." class="iframeclass"width="999px" height="618px"></iframe>
</div>

CSS示例代码:

.iframeclass{
    position: absolute;
    top: 0;
    width: 100%;
}

.iframecontainer{
    position: relative;
    width: 100%;
    height: auto;
    padding-top: 61%;
}

答案 18 :(得分:0)

要添加到似乎在底部切断的窗口块,特别是当您没有使用滚动时:

function resizeIframe(iframe) {
    var addHeight = 20; //or whatever size is being cut off
    iframe.height = iframe.contentWindow.document.body.scrollHeight + addHeight + "px";
  }

答案 19 :(得分:0)

我发现特洛伊的答案没有用。这是为ajax重写的相同代码:

$.ajax({                                      
    url: 'data.php',    
    dataType: 'json',                             

    success: function(data)
    {
        // Put the data onto the page

        // Resize the iframe
        var iframe = $(window.top.document).find("#iframe");
        iframe.height( iframe[0].contentDocument.body.scrollHeight+'px' );
    }
});

答案 20 :(得分:-1)

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

和/或

$(window).height()

请参阅Stack Overflow问题 How to get the height of a body element

尝试使用jQuery查找正文的高度:

if $("body").height()

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