我正在加载一个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内容的高度:
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();
对阿里斯托斯的回答略有改进…
<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);
您可以查看四个不同的属性来获取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');
}
我发现接受的答案是不够的,因为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有一些动态内容,如稍后加载的地图,并动态更改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内容滚动高度,然后清除间隔。