根据内容高度调整iframe的高度

我正在我的网站上打开我的博客页面。 问题是我可以给一个iframe的宽度,但高度应该是dynamic的,以便在iframe中没有滚动条,它看起来像一个单一的页面…

我已经尝试了各种JavaScript代码来计算内容的高度,但他们都给予拒绝访问权限的错误,是没有用的。

<iframe src="http://bagtheplanet.blogspot.com/" name="ifrm" id="ifrm" width="1024px" ></iframe> 

我们可以使用Ajax来计算高度,也可以使用PHP?

直接回答你的两个子问题:不,你不能用Ajax做这个,也不能用PHP来计算。

我过去做的是使用window.onload的iframe页面的一个触发器(不是domready ,因为它可能需要一段时间才能加载图片)将页面的身高传递给父页面。

 <body onload='parent.resizeIframe(document.body.scrollHeight)'> 

然后parent.resizeIframe看起来像这样:

 function resizeIframe(newHeight) { document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px'; } 

等瞧,你有一个强大的调整器触发一旦页面完全呈现没有讨厌contentdocument vs contentWindow摆弄:)

当然,现在人们会首先在默认的高度上看到你的iframe,但是这可以通过首先隐藏iframe来轻松处理,并显示一个“加载”图像。 然后,当resizeIframe函数启动时,在其中放置两条额外的行,这将隐藏加载图像,并显示用于人造Ajax外观的iframe。

当然,这只能在同一个域上运行,所以你可能需要一个代理PHP脚本来embedded这些东西,一旦你去了那里,你也可以直接用PHP将你的Blog的RSS feedembedded到你的站点中。

你可以用JavaScript来做到这一点。

 document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px"; 

拟合IFRAME内容在Google上很容易find 。 这里有一个解决scheme :

 <script type="text/javascript"> function autoIframe(frameId) { try { frame = document.getElementById(frameId); innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document; objToResize = (frame.style) ? frame.style : frame; objToResize.height = innerDoc.body.scrollHeight + 10; } catch(err) { window.status = err.message; } } </script> 

这当然不能解决你所遇到的跨域问题。如果这些站点在同一个地方,设置document.domain可能会有所帮助。 如果你是随机站点,我不认为有一个解决scheme。

这里是我使用MooTools在Firefox 3.6,Safari 4.0.4和Internet Explorer 7中的问题的解决scheme:

 var iframe_container = $('iframe_container_id'); var iframe_style = { height: 300, width: '100%' }; if (!Browser.Engine.trident) { // IE has hasLayout issues if iframe display is none, so don't use the loading class iframe_container.addClass('loading'); iframe_style.display = 'none'; } this.iframe = new IFrame({ frameBorder: 0, src: "http://www.youriframeurl.com/", styles: iframe_style, events: { 'load': function() { var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document; var h = this.measure(function(){ return innerDoc.body.scrollHeight; }); this.setStyles({ height: h.toInt(), display: 'block' }); if (!Browser.Engine.trident) { iframe_container.removeClass('loading'); } } } }).inject(iframe_container); 

设置“加载”类以在iframe容器中间显示一个Ajax加载graphics。 然后,对于Internet Explorer以外的浏览器,一旦加载内容完成,它将显示完整高度的IFRAME,并删除加载graphics。

以下是我的onload事件处理程序。

我在jQuery UI对话框中使用IFRAME。 不同的用法需要一些调整。 这似乎对我来说(现在)在Internet Explorer 8和Firefox 3.5中诀窍。 它可能需要一些额外的调整,但总的想法应该是清楚的。

  function onLoadDialog(frame) { try { var body = frame.contentDocument.body; var $body = $(body); var $frame = $(frame); var contentDiv = frame.parentNode; var $contentDiv = $(contentDiv); var savedShow = $contentDiv.dialog('option', 'show'); var position = $contentDiv.dialog('option', 'position'); // disable show effect to enable re-positioning (UI bug?) $contentDiv.dialog('option', 'show', null); // show dialog, otherwise sizing won't work $contentDiv.dialog('open'); // Maximize frame width in order to determine minimal scrollHeight $frame.css('width', $contentDiv.dialog('option', 'maxWidth') - contentDiv.offsetWidth + frame.offsetWidth); var minScrollHeight = body.scrollHeight; var maxWidth = body.offsetWidth; var minWidth = 0; // decrease frame width until scrollHeight starts to grow (wrapping) while (Math.abs(maxWidth - minWidth) > 10) { var width = minWidth + Math.ceil((maxWidth - minWidth) / 2); $body.css('width', width); if (body.scrollHeight > minScrollHeight) { minWidth = width; } else { maxWidth = width; } } $frame.css('width', maxWidth); // use maximum height to avoid vertical scrollbar (if possible) var maxHeight = $contentDiv.dialog('option', 'maxHeight') $frame.css('height', maxHeight); $body.css('width', ''); // correct for vertical scrollbar (if necessary) while (body.clientWidth < maxWidth) { $frame.css('width', maxWidth + (maxWidth - body.clientWidth)); } var minScrollWidth = body.scrollWidth; var minHeight = Math.min(minScrollHeight, maxHeight); // descrease frame height until scrollWidth decreases (wrapping) while (Math.abs(maxHeight - minHeight) > 10) { var height = minHeight + Math.ceil((maxHeight - minHeight) / 2); $body.css('height', height); if (body.scrollWidth < minScrollWidth) { minHeight = height; } else { maxHeight = height; } } $frame.css('height', maxHeight); $body.css('height', ''); // reset widths to 'auto' where possible $contentDiv.css('width', 'auto'); $contentDiv.css('height', 'auto'); $contentDiv.dialog('option', 'width', 'auto'); // re-position the dialog $contentDiv.dialog('option', 'position', position); // hide dialog $contentDiv.dialog('close'); // restore show effect $contentDiv.dialog('option', 'show', savedShow); // open using show effect $contentDiv.dialog('open'); // remove show effect for consecutive requests $contentDiv.dialog('option', 'show', null); return; } //An error is raised if the IFrame domain != its container's domain catch (e) { window.status = 'Error: ' + e.number + '; ' + e.description; alert('Error: ' + e.number + '; ' + e.description); } }; 

如何dynamic调整iframe的高度真的很简单,并经过我的testing。

@ SchizoDuckie的答案非常优雅和轻量级,但是由于Webkit缺乏对scrollHeight的实现(见这里 ),在基于Webkit的浏览器(Safari,Chrome,各种各样的移动平台)上不起作用。

对于Webkit和Gecko和Trident浏览器的基本思想,只需要replace即可

 <body onload='parent.resizeIframe(document.body.scrollHeight)'> 

 <body onload='parent.resizeIframe(document.body.offsetHeight)'> 

只要一切都在同一个领域,这个工作得很好。

我只花了3天的这一部分摔跤比较好的一部分。 我正在开发一个应用程序,将其他应用程序加载到自己的同时保持一个固定的标题和一个固定的页脚。 这是我想出来的。 (我也使用了EasyXDM,但是成功了,但是稍后再用它来使用这个解决scheme。)

确保在DOM中存在<iframe>之后运行此代码。 把它放入拉iframe(父)的页面。

 // get the iframe var theFrame = $("#myIframe"); // set its height to the height of the window minus the combined height of fixed header and footer theFrame.height(Number($(window).height()) - 80); function resizeIframe() { theFrame.height(Number($(window).height()) - 80); } // setup a resize method to fire off resizeIframe. // use timeout to filter out unnecessary firing. var TO = false; $(window).resize(function() { if (TO !== false) clearTimeout(TO); TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds }); 

诀窍是从外部脚本获取所有必要的iframe事件。 例如,您有一个使用document.createElement创buildiFrame的脚本; 在这个脚本中,您暂时可以访问iFrame的内容。

 var dFrame = document.createElement("iframe"); dFrame.src = "http://www.example.com"; // Acquire onload and resize the iframe dFrame.onload = function() { // Setting the content window's resize function tells us when we've changed the height of the internal document // It also only needs to do what onload does, so just have it call onload dFrame.contentWindow.onresize = function() { dFrame.onload() }; dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px"; } window.onresize = function() { dFrame.onload(); } 

这是可行的,因为dFrame停留在这些函数的作用域中,使您可以在框架范围内访问外部iFrame元素,从而可以看到实际的文档高度并根据需要展开它。 这个例子将在Firefox中工作,但在其他地方; 我可以给你的解决方法,但你可以找出其余的;)

试试这个,即使你想要,也可以改变。 这个例子使用jQuery。

 $('#iframe').live('mousemove', function (event) { var theFrame = $(this, parent.document.body); this.height($(document.body).height() - 350); }); 

尝试在iframe标签上使用scrolling=no属性。 Mozilla也有一个overflow-xoverflow-y CSS属性,你可以看看。

就高度而言,您也可以在iframe标签上尝试height=100%