我正在 iframe 中加载一个 aspx 网页。 iframe 中的内容可以比 iframe 的高度更高。 iframe 不应有滚动条。
我在 iframe 中有一个包装器 div
标记,它基本上是所有内容。我写了一些 jQuery 来实现调整大小:
$("#TB_window", window.parent.document).height($("body").height() + 50);
其中 TB_window
是包含 Iframe
的 div。
body
- iframe 中 aspx 的正文标记。
此脚本附加到 iframe 内容。我正在从父页面获取 TB_window
元素。虽然这在 Chrome 上运行良好,但 TB_window 在 Firefox 中崩溃。我真的很困惑/迷失了为什么会发生这种情况。
您可以使用以下方法检索 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()" ...
前段时间我遇到过一种情况,在其中发生表单提交后,我还需要从 IFRAME
本身调用 iframeLoaded
。您可以通过在 IFRAME
的内容脚本中执行以下操作来完成此操作:
parent.iframeLoaded();
对 Aristos 的稍微改进的答案......
<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);
resizeIframe
使 iframe 比当前更小,我相信 iFrameID.height = "";
(或将其设置为“20px”)是必要的。例如,如果您在父窗口调整大小时触发此操作,如果窗口 & iframe 变得更宽,并且您希望 iframe 结果缩小高度,您需要那条线。这是必要的,因为只有当 iframe 当前的大小小于 小于所需的内容高度时,iframe.contentWindow.document.body.scrollHeight
才准确。
我发现接受的答案还不够,因为 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 标记以触发调整大小功能:
<body onLoad="resize();">
setInterval(resize, 1000);
将此添加到 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');
}
您还可以将重复的 requestAnimationFrame 添加到您的 resizeIframe (例如,来自@BlueFish 的答案),它总是在浏览器绘制布局之前被调用,并且您可以在 iframe 的内容改变其高度时更新 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)" ...
您的回调应该足够快,不会对您的整体表现产生太大影响
body
是 null
,所以刚遇到一个案例 Uncaught TypeError: Cannot read property 'scrollHeight' of null
,但它通常可以工作。
其他答案对我不起作用,所以我做了一些更改。希望这会有所帮助
$('#iframe').on("load", function() {
var iframe = $(window.top.document).find("#iframe");
iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});
以防万一这对任何人都有帮助。我正在拔头发试图让它工作,然后我注意到 iframe 有一个高度为 100% 的类条目。当我删除它时,一切都按预期工作。因此,请检查是否存在任何 css 冲突。
我正在使用 jQuery 和下面的代码为我工作,
var iframe = $(window.top.document).find("#iframe_id_here");
iframe.height(iframe.contents().height()+'px' );
您可以在此处参考相关问题 - How to make width and height of iframe same as its parent div?
设置动态高度 -
我们需要与跨域 iFrame 和父窗口进行通信然后我们可以将 iframe 的滚动高度/内容高度发送到父窗口
和代码 - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8
而不是使用 javscript/jquery 我发现最简单的方法是:
这里 1vh = 浏览器窗口高度的 1%。所以要设置的理论高度值为 100vh,但实际上 98vh 起到了神奇的作用。
所有其他答案都是正确的,但是如果 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>
this.contentDocument is null
我发现特洛伊的答案不起作用。这是为 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";
}
当您需要没有 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 像素,因此底部的填充为 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%;
}
对 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";
}
这考虑了 Windows 屏幕(浏览器、手机)的高度,这对于响应式设计和具有巨大高度的 iframe 非常有用。填充表示在 iframe 穿过整个屏幕的情况下您希望在 iframe 上方和下方的填充。
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);
});
使用 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>';
$(document).height() // - $('body').offset().top
和/或
$(window).height()
请参阅堆栈溢出问题How to get the height of a body element。
试试这个在 jQuery 中找到 body 的高度:
if $("body").height()
如果 Firebug 没有值。也许这就是问题所在。
只需使 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>
X-FRAME-OPTIONS
以添加一行:Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
或response.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");