我正在开发一个类似 iGoogle 的应用程序。来自其他应用程序(在其他域上)的内容使用 iframe 显示。
如何调整 iframe 的大小以适应 iframe 内容的高度?
我试图破译谷歌使用的 javascript,但它被混淆了,到目前为止搜索网络没有结果。
更新:请注意,内容是从其他域加载的,因此 same-origin policy 适用。
我们遇到了此类问题,但与您的情况稍有相反 - 我们将 iframe 内容提供给其他域上的网站,因此 same origin policy 也是一个问题。在谷歌搜索了很多小时后,我们最终找到了一个(有点..)可行的解决方案,您可能能够适应您的需求。
有一种方法可以绕过同源策略,但它需要对 iframed 内容和框架页面进行更改,因此如果您无法在双方都请求更改,此方法对您来说不是很有用,我耽心。
有一个浏览器怪癖允许我们绕过同源策略 - javascript 可以与它自己域上的页面通信,或者与它具有 iframe 的页面通信,但不能与它被框架的页面通信,例如,如果你有:
www.foo.com/home.html, which iframes
|-> www.bar.net/framed.html, which iframes
|-> www.foo.com/helper.html
那么 home.html
可以与 framed.html
(iframed)和 helper.html
(同一个域)通信。
Communication options for each page:
+-------------------------+-----------+-------------+-------------+
| | home.html | framed.html | helper.html |
+-------------------------+-----------+-------------+-------------+
| www.foo.com/home.html | N/A | YES | YES |
| www.bar.net/framed.html | NO | N/A | YES |
| www.foo.com/helper.html | YES | YES | N/A |
+-------------------------+-----------+-------------+-------------+
framed.html
可以向 helper.html
(iframed)发送消息,但不能 home.html
(子级无法与父级跨域通信)。
这里的关键是helper.html
可以接收来自framed.html
的消息,并且还可以与home.html
通信。
因此,本质上,当 framed.html
加载时,它会计算出自己的高度,并告诉 helper.html
,后者将消息传递给 home.html
,然后它可以调整 framed.html
所在的 iframe 的大小。
我们发现将消息从 framed.html
传递到 helper.html
的最简单方法是通过 URL 参数。为此,framed.html
有一个指定了 src=''
的 iframe。当它的 onload
触发时,它会评估自己的高度,并将 iframe 的 src 此时设置为 helper.html?height=N
There's an explanation here facebook 如何处理它,这可能比我上面的更清楚!
代码
在 www.foo.com/home.html
中,需要以下 javascript 代码(可以从任何域上的 .js 文件加载,顺便说一句..):
<script>
// Resize iframe to full height
function resizeIframe(height)
{
// "+60" is a general rule of thumb to allow for differences in
// IE & and FF height reporting, can be adjusted as required..
document.getElementById('frame_name_here').height = parseInt(height)+60;
}
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>
在 www.bar.net/framed.html
中:
<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>
<script type="text/javascript">
function iframeResizePipe()
{
// What's the page height?
var height = document.body.scrollHeight;
// Going to 'pipe' the data to the parent through the helpframe..
var pipe = document.getElementById('helpframe');
// Cachebuster a precaution here to stop browser caching interfering
pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();
}
</script>
www.foo.com/helper.html
的内容:
<html>
<!--
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content
-->
<body onload="parentIframeResize()">
<script>
// Tell the parent iframe what height the iframe needs to be
function parentIframeResize()
{
var height = getParam('height');
// This works as our parent's parent is on our domain..
parent.parent.resizeIframe(height);
}
// Helper function, parse param from request string
function getParam( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
</script>
</body>
</html>
如果您不需要处理来自不同域的 iframe 内容,请尝试使用此代码,它将彻底解决问题,而且很简单:
<script language="JavaScript">
<!--
function autoResize(id){
var newheight;
var newwidth;
if(document.getElementById){
newheight=document.getElementById(id).contentWindow.document .body.scrollHeight;
newwidth=document.getElementById(id).contentWindow.document .body.scrollWidth;
}
document.getElementById(id).height= (newheight) + "px";
document.getElementById(id).width= (newwidth) + "px";
}
//-->
</script>
<iframe src="usagelogs/default.aspx" width="100%" height="200px" id="iframe1" marginheight="0" frameborder="0" onLoad="autoResize('iframe1');"></iframe>
document.getElementById(id)
并简化代码。
https://developer.mozilla.org/en/DOM/window.postMessage
window.postMessage() window.postMessage 是一种安全启用跨域通信的方法。通常,不同页面上的脚本只有当且仅当执行它们的页面位于具有相同协议(通常都是 http)、端口号(http 的默认值为 80)和主机(模document.domain 被两个页面设置为相同的值)。 window.postMessage 提供了一种受控机制,以在正确使用时以一种安全的方式规避此限制。摘要 window.postMessage,当调用时,会在必须执行的任何挂起脚本完成时在目标窗口调度 MessageEvent(例如,如果从事件处理程序调用 window.postMessage,则剩余的事件处理程序,先前设置的挂起超时等.)。 MessageEvent 具有消息类型,数据属性设置为提供给 window.postMessage 的第一个参数的字符串值,原始属性对应于在时间窗口调用 window.postMessage 的窗口中的主文档的来源。 postMessage 被调用,源属性是调用 window.postMessage 的窗口。 (事件的其他标准属性与它们的期望值一起出现。)
iFrame-Resizer 库使用 postMessage 来保持 iFrame 的大小与其内容一致,并使用 MutationObserver 来检测内容的更改,并且不依赖于 jQuery。
https://github.com/davidjbradshaw/iframe-resizer
jQuery:跨域脚本的优点
http://benalman.com/projects/jquery-postmessage-plugin/
有调整 iframe 窗口大小的演示......
http://benalman.com/code/projects/jquery-postmessage/examples/iframe/
这篇文章展示了如何移除对 jQuery 的依赖... Plus 有很多有用的信息和其他解决方案的链接。
http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/
准系统示例...
http://onlineaspect.com/uploads/postmessage/parent.html
window.postMessage 上的 HTML 5 工作草案
http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
John Resig 谈跨窗口消息传递
http://ejohn.org/blog/cross-window-messaging/
使用 jQuery 的最简单方法:
$("iframe")
.attr({"scrolling": "no", "src":"http://www.someotherlink.com/"})
.load(function() {
$(this).css("height", $(this).contents().height() + "px");
});
最后,我找到了使用 window.postMessage(message, targetOrigin);
从 iframe 向父网站发送数据的其他解决方案。在这里,我解释了我是如何做到的。
站点 A = http://foo.com 站点 B = http://bar.com
SiteB 正在 siteA 网站内加载
SiteB网站有这条线
window.parent.postMessage("Hello From IFrame", "*");
或者
window.parent.postMessage("Hello From IFrame", "http://foo.com");
然后siteA有以下代码
// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
alert(e.data);
// Do whatever you want to do with the data got from IFrame in Parent form.
}, false);
如果您想添加安全连接,您可以在 eventer(messageEvent, function (e) {})
中使用此 if 条件
if (e.origin == 'http://iframe.example.com') {
alert(e.data);
// Do whatever you want to do with the data got from IFrame in Parent form.
}
对于 IE
内部 IFrame:
window.parent.postMessage('{"key":"value"}','*');
外部:
eventer(messageEvent, function (e) {
var data = jQuery.parseJSON(e.data);
doSomething(data.key);
}, false);
http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html 上的解决方案效果很好(使用 jQuery):
<script type=”text/javascript”>
$(document).ready(function() {
var theFrame = $(”#iFrameToAdjust”, parent.document.body);
theFrame.height($(document.body).height() + 30);
});
</script>
我不知道您需要在长度上加 30 ... 1 对我有用。
仅供参考:如果您的 iFrame 上已有“高度”属性,则只需添加 style="height: xxx"。这可能不是你想要的。
可能有点晚了,因为所有其他答案都较旧:-) 但是......这是我的解决方案。在实际的 FF、Chrome 和 Safari 5.0 中测试。
CSS:
iframe {border:0; overflow:hidden;}
javascript:
$(document).ready(function(){
$("iframe").load( function () {
var c = (this.contentWindow || this.contentDocument);
if (c.document) d = c.document;
var ih = $(d).outerHeight();
var iw = $(d).outerWidth();
$(this).css({
height: ih,
width: iw
});
});
});
希望这会帮助任何人。
此答案仅适用于使用 Bootstrap 的网站。 Bootstrap 的响应式嵌入功能可以完成这项工作。它基于内容的宽度(而不是高度)。
<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="http://www.youtube.com/embed/WsFWhL4Y84Y"></iframe>
</div>
jsfiddle:http://jsfiddle.net/00qggsjj/2/
http://getbootstrap.com/components/#responsive-embed
这是一个简单的解决方案,它使用由同一服务器提供的动态生成的样式表作为 iframe 内容。很简单,样式表“知道” iframe 中的内容,并且知道用于设置 iframe 样式的尺寸。这绕过了相同的来源政策限制。
http://www.8degrees.co.nz/2010/06/09/dynamically-resize-an-iframe-depending-on-its-content/
所以提供的 iframe 代码会有一个随附的样式表,像这样......
<link href="http://your.site/path/to/css?contents_id=1234&dom_id=iframe_widget" rel="stylesheet" type="text/css" />
<iframe id="iframe_widget" src="http://your.site/path/to/content?content_id=1234" frameborder="0" width="100%" scrolling="no"></iframe>
这确实需要服务器端逻辑能够计算 iframe 呈现内容的尺寸。
我正在实施 ConroyP 的 frame-in-frame 解决方案来替换基于设置 document.domain 的解决方案,但发现在不同的浏览器中正确确定 iframe 内容的高度非常困难(现在使用 FF11、Ch17 和 IE9 进行测试)。
ConroyP 使用:
var height = document.body.scrollHeight;
但这仅适用于初始页面加载。我的 iframe 具有动态内容,我需要在某些事件上调整 iframe 的大小。
我最终做的是为不同的浏览器使用不同的 JS 属性。
function getDim () {
var body = document.body,
html = document.documentElement;
var bc = body.clientHeight;
var bo = body.offsetHeight;
var bs = body.scrollHeight;
var hc = html.clientHeight;
var ho = html.offsetHeight;
var hs = html.scrollHeight;
var h = Math.max(bc, bo, bs, hc, hs, ho);
var bd = getBrowserData();
// Select height property to use depending on browser
if (bd.isGecko) {
// FF 11
h = hc;
} else if (bd.isChrome) {
// CH 17
h = hc;
} else if (bd.isIE) {
// IE 9
h = bs;
}
return h;
}
getBrowserData() 是受 Ext Core 的 http://docs.sencha.com/core/source/Ext.html#method-Ext-apply “启发”的浏览器检测功能
这对 FF 和 IE 来说效果很好,但是 Chrome 出现了问题。其中之一是时间问题,显然 Chrome 需要一段时间来设置/检测 iframe 的高度。如果 iframe 高于内容,Chrome 也永远不会正确返回 iframe 中内容的高度。当高度降低时,这不适用于动态内容。
为了解决这个问题,我总是在检测内容高度之前将 iframe 设置为较低的高度,然后将 iframe 高度设置为正确的值。
function resize () {
// Reset the iframes height to a low value.
// Otherwise Chrome won't detect the content height of the iframe.
setIframeHeight(150);
// Delay getting the dimensions because Chrome needs
// a few moments to get the correct height.
setTimeout("getDimAndResize()", 100);
}
代码没有优化,它来自我的开发测试:)
希望有人觉得这有帮助!
<html>
<head>
<script>
function frameSize(id){
var frameHeight;
document.getElementById(id).height=0 + "px";
if(document.getElementById){
newheight=document.getElementById(id).contentWindow.document.body.scrollHeight;
}
document.getElementById(id).height= (frameHeight) + "px";
}
</script>
</head>
<body>
<iframe id="frame" src="startframe.html" frameborder="0" marginheight="0" hspace=20 width="100%"
onload="javascript:frameSize('frame');">
<p>This will work, but you need to host it on an http server, you can do it locally. </p>
</body>
</html>
这是一个旧线程,但在 2020 年它仍然是一个相关问题。我实际上也在另一个旧线程中发布了这个答案^^ (https://stackoverflow.com/a/64110252/4383587)
只是想分享我的解决方案和兴奋。我花了整整四天的时间进行深入的研究和失败,但我认为我找到了一种让 iframe 完全响应的巧妙方法!耶!
我尝试了很多不同的方法......我不想像 postMessage
那样使用双向通信隧道,因为它对于同源来说很尴尬并且对于跨域来说很复杂(因为没有管理员想要打开门和代表您实施)。
我已经尝试使用 MutationObservers 并且仍然需要几个 EventListeners(调整大小、单击、..)以确保正确处理布局的每个更改。 - 如果脚本切换元素的可见性怎么办?或者,如果它按需动态预加载更多内容呢? - 另一个问题是从某个地方获取 iframe 内容的准确高度。大多数人建议使用 scrollHeight
或 offsetHeight
,或通过使用 Math.max
组合使用。问题是,在 iframe 元素更改其尺寸之前,这些值不会更新。要实现这一点,您可以在获取 scrollHeight
之前简单地重置 iframe.height = 0
,但对此还有更多警告。所以,拧这个。
然后,我有了另一个想法,尝试用 requestAnimationFrame
摆脱我的事件和观察者地狱。现在,我可以立即对每个布局更改做出反应,但我仍然没有可靠的来源来推断 iframe 的内容高度。我偶然发现了getComputedStyle
!这是一个启示!一切都刚刚好。
好吧,看看我最终可以从无数次尝试中提取的代码。
function fit() {
var iframes = document.querySelectorAll("iframe.gh-fit")
for(var id = 0; id < iframes.length; id++) {
var win = iframes[id].contentWindow
var doc = win.document
var html = doc.documentElement
var body = doc.body
var ifrm = iframes[id] // or win.frameElement
if(body) {
body.style.overflowX = "scroll" // scrollbar-jitter fix
body.style.overflowY = "hidden"
}
if(html) {
html.style.overflowX = "scroll" // scrollbar-jitter fix
html.style.overflowY = "hidden"
var style = win.getComputedStyle(html)
ifrm.width = parseInt(style.getPropertyValue("width")) // round value
ifrm.height = parseInt(style.getPropertyValue("height"))
}
}
requestAnimationFrame(fit)
}
addEventListener("load", requestAnimationFrame.bind(this, fit))
就是这样,是的! - 在您的 HTML 代码中写入 <iframe src="page.html" class="gh-fit gh-fullwidth"></iframe>
。 gh-fit
只是一个虚假的 CSS 类,用于识别 DOM 中的哪些 iframe 元素应受脚本影响。 gh-fullwidth
是具有一条规则 width: 100%;
的简单 CSS 类。
上面的脚本会自动从 DOM 中获取所有分配有 .gh-fit
类的 iframe。然后它从 document.getComputedStyle(iframe)
中获取并使用预先计算的宽度和高度样式值,这些值始终包含该元素的像素完美大小!!!刚刚好!
请注意,此解决方案不能跨域工作(没有任何其他解决方案,没有像 IFrameResizer 这样的双向通信策略)。 JS 根本无法访问不属于您的 iframe 的 DOM。
我能想到的唯一其他跨域解决方案是使用像 https://github.com/gnuns/allorigins 这样的代理。但这将涉及深度复制您发出的每个请求 - 换句话说 - 您“窃取”整个页面源代码(使其成为您的并让 JS 访问 DOM)并修补此源中的每个链接/路径,以便它也通过代理。重新链接例程是一个艰难的例程,但可行。
我可能会尝试解决这个跨域问题,但那是另一天。享受代码! :)
如果您可以控制 iframe 内容,我强烈建议您使用
调整大小观察者
只需在 iframe
的 srcdoc
属性的末尾插入以下内容,如果需要,escape 即可。
<script type="text/javascript">
var ro = new ResizeObserver(entries => {
for (let entry of entries) {
const cr = entry.contentRect;
// console.log(window.frameElement);
window.frameElement.style.height =cr.height +30+ "px";
}
});
ro.observe(document.body);
</script>
iGoogle 小工具必须主动实现调整大小,所以我的猜测是在跨域模型中,如果没有远程内容以某种方式参与,您将无法做到这一点。如果您的内容可以使用典型的跨域通信技术向容器页面发送具有新大小的消息,那么剩下的就很简单了。
当您想要缩小网页以使其适合 iframe 大小时:
您应该调整 iframe 的大小以使其适合内容然后您应该使用加载的网页内容缩小整个 iframe
这是一个例子:
<div id="wrap">
<IFRAME ID="frame" name="Main" src ="http://www.google.com" />
</div>
<style type="text/css">
#wrap { width: 130px; height: 130px; padding: 0; overflow: hidden; }
#frame { width: 900px; height: 600px; border: 1px solid black; }
#frame { zoom:0.15; -moz-transform:scale(0.15);-moz-transform-origin: 0 0; }
</style>
这是一个 jQuery 方法,它通过 iframe 的 src 属性在 json 中添加信息。这是一个演示,调整大小并滚动此窗口.. 带有 json 的结果 url 看起来像这样... http://fiddle.jshell.net/zippyskippy/RJN3G/show/#{docHeight:5124,windowHeight:1019,scrollHeight:571}#
这是源代码小提琴http://jsfiddle.net/zippyskippy/RJN3G/
function updateLocation(){
var loc = window.location.href;
window.location.href = loc.replace(/#{.*}#/,"")
+ "#{docHeight:"+$(document).height()
+ ",windowHeight:"+$(window).height()
+ ",scrollHeight:"+$(window).scrollTop()
+"}#";
};
//setInterval(updateLocation,500);
$(window).resize(updateLocation);
$(window).scroll(updateLocation);
获取 iframe 内容高度,然后将其提供给此 iframe
var iframes = document.getElementsByTagName("iframe");
for(var i = 0, len = iframes.length; i<len; i++){
window.frames[i].onload = function(_i){
return function(){
iframes[_i].style.height = window.frames[_i].document.body.scrollHeight + "px";
}
}(i);
}
在加载时使用 jquery(跨浏览器):
<iframe src="your_url" marginwidth="0" marginheight="0" scrolling="No" frameborder="0" hspace="0" vspace="0" id="containiframe" onload="loaderIframe();" height="100%" width="100%"></iframe>
function loaderIframe(){
var heightIframe = $('#containiframe').contents().find('body').height();
$('#frame').css("height", heightFrame);
}
在响应页面中调整大小:
$(window).resize(function(){
if($('#containiframe').length !== 0) {
var heightIframe = $('#containiframe').contents().find('body').height();
$('#frame').css("height", heightFrame);
}
});
David Bradshaw 和 Chris Jacob 已经建议使用 postMessage 方法。我完全同意,做这些事情的正确方法。
我只想发布一个示例,真实有效的代码,以防它成为某些人的现成答案。
在 iframe 方面:
<body onload="docResizePipe()">
<script>
var v = 0;
const docResizeObserver = new ResizeObserver(() => {
docResizePipe();
});
docResizeObserver.observe(document.querySelector("body"));
function docResizePipe() {
v += 1;
if (v > 5) {
return;
}
var w = document.body.scrollWidth;
var h = document.body.scrollHeight;
window.parent.postMessage([w,h], "*");
}
setInterval(function() {
v -= 1;
if (v < 0) {
v = 0;
}
}, 300);
</script>
注意递归阻塞机制——这是必要的,因为 Firefox 中显然存在一个错误,但无论如何让它在那里。
在父文档方面:
<iframe id="rpa-frame" src="3.html" style="border: none;"></iframe>
<script>
var rpaFrame = document.getElementById("rpa-frame");
window.addEventListener("message", (event) => {
var width = event.data[0];
var height = event.data[1];
rpaFrame.width = parseInt(width)+60;
rpaFrame.height = parseInt(height)+60;
console.log(event);
}, false);
</script>
希望它会有用。
我在这里阅读了很多答案,但几乎每个人都给出了某种跨域框架块。
示例错误:
未捕获的 DOMException:阻止具有源“null”的框架访问跨域框架。
相关线程中的答案也是如此:
Make iframe automatically adjust height according to the contents without using scrollbar?
我也不想使用像 iFrame Resizer
这样的第三方库或类似的库。
@ChrisJacob 的答案很接近,但我缺少一个完整的工作示例,而不仅仅是链接。 @Selvamani 和 @latitov 也是很好的补充。
https://stackoverflow.com/a/3219970/3850405
我将 width="100%"
用于 iframe
,但也可以修改代码以使用宽度。
这就是我解决为 iframe
设置自定义高度的方法:
嵌入式 iframe
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description"
content="Web site" />
<title>Test with embedded iframe</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<iframe id="ifrm" src="https://localhost:44335/package/details?key=123" width="100%"></iframe>
<script type="text/javascript">
window.addEventListener('message', receiveMessage, false);
function receiveMessage(evt) {
console.log("Got message: " + JSON.stringify(evt.data) + " from origin: " + evt.origin);
// Do we trust the sender of this message?
if (evt.origin !== "https://localhost:44335") {
return;
}
if (evt.data.type === "frame-resized") {
document.getElementById("ifrm").style.height = evt.data.value + "px";
}
}
</script>
</body>
</html>
iframe source
,来自 Create React App
的示例,但仅使用了 HTML
和 JS
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description"
content="Web site created using create-react-app" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript">
//Don't run unless in an iframe
if (self !== top) {
var rootHeight;
setInterval(function () {
var rootElement = document.getElementById("root");
if (rootElement) {
var currentRootHeight = rootElement.offsetHeight;
//Only send values if height has changed since last time
if (rootHeight !== currentRootHeight) {
//postMessage to set iframe height
window.parent.postMessage({ "type": "frame-resized", "value": currentRootHeight }, '*');
rootHeight = currentRootHeight;
}
}
}
, 1000);
}
</script>
</body>
</html>
带有 setInterval
的代码当然可以修改,但它非常适合动态内容。 setInterval
仅在内容嵌入 iframe
时激活,并且 postMessage
仅在高度更改时发送消息。
您可以在此处阅读有关 Window.postMessage()
的更多信息,但该描述非常符合我们想要实现的目标:
window.postMessage() 方法可以安全地启用 Window 对象之间的跨域通信;例如,在页面和它生成的弹出窗口之间,或者在页面和嵌入其中的 iframe 之间。通常,当且仅当它们源自的页面共享相同的协议、端口号和主机(也称为“同源策略”)时,才允许不同页面上的脚本相互访问。 window.postMessage() 提供了一种受控机制来安全地规避此限制(如果使用得当)。
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
使用 jQuery:
父.html
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<style>
iframe {
width: 100%;
border: 1px solid black;
}
</style>
<script>
function foo(w, h) {
$("iframe").css({width: w, height: h});
return true; // for debug purposes
}
</script>
<iframe src="child.html"></iframe>
</body>
child.html
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(function() {
var w = $("#container").css("width");
var h = $("#container").css("height");
var req = parent.foo(w, h);
console.log(req); // for debug purposes
});
</script>
<style>
body, html {
margin: 0;
}
#container {
width: 500px;
height: 500px;
background-color: red;
}
</style>
<div id="container"></div>
</body>
找不到可以完美处理大文本+大图像的东西,但我最终得到了这个,似乎每次都正确或几乎正确:
iframe.addEventListener("load",function(){
// inlineSize, length, perspectiveOrigin, width
let heightMax = 0;
// this seems to work best with images...
heightMax = Math.max(heightMax,iframe.contentWindow.getComputedStyle(iframe.contentWindow.document.body).perspectiveOrigin.split("px")[0]);
// this seems to work best with text...
heightMax = Math.max(heightMax,iframe.contentWindow.document.body.scrollHeight);
// some large 1920x1080 images always gets a little bit off on firefox =/
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if(isFirefox && heightMax >= 900){
// grrr..
heightMax = heightMax + 100;
}
iframe.style.height = heightMax+"px";
//console.log(heightMax);
});
这有点棘手,因为您必须知道 iframe 页面何时加载,当您无法控制其内容时,这很困难。可以将 onload 处理程序添加到 iframe,但我过去曾尝试过,并且它在浏览器之间的行为有很大不同(不知道谁是最烦人的......)。您可能必须向 iframe 页面添加一个函数来执行调整大小并将一些脚本注入到内容中,以监听加载事件或调整大小事件,然后调用前一个函数。我正在考虑向页面添加一个功能,因为你想确保它的安全,但我不知道它会有多容易。
我相信这方面的东西应该有效。
parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;
在 iframe 内容上使用您的 body onload 加载它。
我有一个简单的解决方案,需要您确定链接中的宽度和高度,请尝试(它适用于大多数浏览器):
<a href='#' onClick=" document.getElementById('myform').src='t2.htm';document.getElementById('myform').width='500px'; document.getElementById('myform').height='400px'; return false">500x400</a>
parentIframeResize()
,而是使用 JQuery 来捕获页面加载和任何调整大小的事件:$(document).ready(iframeResizePipe); $(window).resize(iframeResizePipe);
这允许我设置 iframewidth="100%"
以及如果窗口宽度更改以使文本换行或其他内容,内部框架将识别出它需要调整大小。