使iframe高度动态基于内容里面- JQUERY/Javascript

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

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

$("#TB_window", window.parent.document).height($("body").height() + 50);
< p >, TB_window是包含Iframe的div

body - iframe中aspx的body标签。

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

533073 次浏览
你可以通过使用以下方法获取IFRAME的内容的高度: contentWindow.document.body.scrollHeight < / p >

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()" ...

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

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

和/或

$(window).height()

参见堆栈溢出问题如何获得一个体元素的高度

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

if $("body").height()

它没有值if Firebug。也许这就是问题所在。

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

<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元素时引起开销。
< p >编辑: 如果帧中的内容总是在变化,则调用:

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);

我发现特洛伊的答案不管用。这是为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' );
}
});

为了增加窗口底部似乎被切断的部分,特别是当你没有滚动时,我使用了:

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

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

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

不幸的是,他们都可以给出不同的答案,这些是不一致的浏览器。如果将正文边距设置为0,则document.body.offsetHeight将给出最佳答案。要得到正确的值,请尝试这个函数;它取自< a href = " https://github.com/davidjbradshaw/iframe-resizer " > 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');
}

我发现接受的答案是不够的,因为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中,这对我来说很管用:

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

如果你使用jQuery,试试下面的代码:

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

你可以在这里参考相关问题- 如何使iframe的宽度和高度与其父div相同?

设置动态高度-

  1. 我们需要与跨域iFrames和父通信
  2. 然后我们可以将iframe的滚动高度/内容高度发送到父窗口

和代码- https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8

当您需要一个不使用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%;
}

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

在本例中,测量值为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%;
}

对蓝鱼的回答略有改进…

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上方和下方的填充,在这种情况下它贯穿整个屏幕。< / p >
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);
});

比起使用javscript/jquery,我发现最简单的方法是:

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

Here 1vh = 1% of Browser window height. So the theoretical value of height to be set is 100vh but practically 98vh did the magic.

以防这能帮到谁。我拽着我的头发试图让这个工作,然后我注意到iframe有一个类入口高度:100%。当我移除这个,一切都按照预期工作。所以,请检查任何css冲突。

你也可以添加一个重复的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)" ...

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

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

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

示例使用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>';

只需要将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>

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

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

所有其他答案都是正确的,但如果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内容滚动高度,然后清除间隔。

在我的项目中,有一个要求,我们已经使动态屏幕如仪表板的对齐,同时加载,它应该显示在整个页面上,应该得到动态调整,如果用户是最大化或调整浏览器的窗口。 为此,我创建了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>