我的javascript体验中最困难的问题之一是 iframe高度的正确(即“跨浏览器”)计算。 在我的应用程序中,我有很多动态生成的iframe,我希望它们都在load事件结束时做一些autoresize来调整它们的高度和宽度。
在高度计算的情况下,我的最佳解决方案如下(在jQuery的帮助下):
function getDocumentHeight(doc) {
var mdoc = doc || document;
if (mdoc.compatMode=='CSS1Compat') {
return mdoc.body.offsetHeight;
}
else {
if ($.browser.msie)
return mdoc.body.scrollHeight;
else
return Math.max($(mdoc).height(), $(mdoc.body).height());
}
}
我没有成功搜索互联网。我还测试了雅虎库,它有一些文档和视口尺寸的方法,但它并不令人满意。
我的解决方案工作正常,但有时它会计算出更高的高度。
我已经在Firefox / IE / Safari中研究并测试了大量有关文档高度的属性:documentElement.clientHeight, documentElement.offsetHeight, documentElement.scrollHeight, body.offsetHeight, body.scrollHeight, ...
此外,jQuery在调用$(document.body).height(), $('html', doc).height(), $(window).height()
我不仅在load事件结束时调用上面的函数,而且在动态插入DOM元素或隐藏或显示的元素的情况下调用上述函数。这种情况有时会破坏仅在load事件中起作用的代码。
有人拥有真正的跨浏览器(至少是Firefox / IE / Safari)解决方案吗?一些提示或提示?
答案 0 :(得分:4)
虽然我喜欢你的解决方案,但我总是发现IFRAME比它们的价值更麻烦。
为什么? 1.尺寸问题。 2. iframe有src属性需要担心。即绝对路径。 3.页面的额外复杂性。
我的解决方案 - 通过AJAX调用动态加载的DIV。 DIV将自动调整大小。虽然AJAX代码需要javascript工作(可以通过框架完成),但它们与网站的位置有关。 3是一个洗,你交易的页面复杂到javascript。
而不是< IFRAME ...>使用< DIV id =“mystuff”/>
执行ajax调用以使用数据填充mystuff div并让浏览器担心它。
答案 1 :(得分:2)
这一段时间以来一直没有得到公认的答案,所以我想在经过一些研究后提供最终结果的解决方案。 这是跨浏览器和跨域名(例如,当iframe指向来自其他域的内容时)
我最终使用包含在jQuery pluging中的html5的消息传递机制,使其与使用各种方法的旧浏览器兼容(其中一些在此线程中描述)。
最终解决方案非常简单。
在主持人(父)页面上:
// executes when a message is received from the iframe, to adjust
// the iframe's height
$.receiveMessage(
function( event ){
$( 'my_iframe' ).css({
height: event.data
});
});
// Please note this function could also verify event.origin and other security-related checks.
在iframe页面上:
$(function(){
// Sends a message to the parent window to tell it the height of the
// iframe's body
var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
$.postMessage(
$('body').outerHeight( true ) + 'px',
'*',
target
);
});
我在XP和W7上的Chrome 13 +,Firefox 3.6 +,IE7,8和9上进行了测试,在OSX和W7上进行了测试。 ;)
答案 2 :(得分:1)
因为在你的例子中你正在访问里面的文件,所以我想你正在谈论知道文件的高度而不是框架本身。此外,这意味着内容来自您自己的网站,您可以控制它的内容。
那么,为什么不简单地在你的内容周围放置一个DIV,然后使用那个DIV的clientHeight?
您在IFRAME中加载的代码:
...
<body>
<div id="content">
...
</div>
</body>
父文件:
function getDocumentHeight(mdoc) {
return mdoc.getElementById("content").clientHeight;
}
顺便说一下,你的示例函数的这一部分没有意义,因为“document”没有引用IFRAME:
var mdoc = doc || document;
答案 3 :(得分:0)
这是一个似乎有效的解决方案。基本上,在大多数情况下,scrollHeight是正确的值。但是,在IE(特别是6和7)中,如果内容仅包含在文本节点中,则不计算高度,只是默认为CSS中设置的高度或iframe上的“height”属性。这是通过反复试验找到的,所以请把它当作值得的。
function getDocumentHeight(doc) {
var mdoc = doc || document;
var docHeight = mdoc.body.scrollHeight;
if ($.browser.msie) {
// IE 6/7 don't report body height correctly.
// Instead, insert a temporary div containing the contents.
var child = $("<div>" + mdoc.body.innerHTML + "</div>", mdoc);
$("body", mdoc).prepend(child);
docHeight = child.height();
child.remove();
}
return docHeight;
}
答案 4 :(得分:0)
我发现这个解决方案适用于6 +,ff 3.5 +,safari 4+。我正在创建并向文档追加iframe。在执行了一些其他dom操作之后,在jQuery的load事件结束时执行以下代码。由于在load事件中发生了额外的dom操作,因此我需要超时。
// sizing - slight delay for good scrollheight
setTimeout(function() {
var intContentHeight = objContentDoc.body.scrollHeight;
var $wrap = $("#divContentWrapper", objContentFrameDoc);
var intMaxHeight = getMaxLayeredContentHeight($wrap);
$this.height(intContentHeight > intMaxHeight ? intMaxHeight : intContentHeight);
// animate
fireLayeredContentAnimation($wrap);
}, 100);
我需要考虑一些大小调整限制,这就是getMaxLayeredContentHeight调用为我检查的内容。希望有所帮助。
答案 5 :(得分:0)
Here's a script根据身高的高度来调整iFrame的大小。