我正在开发一个类似igoogle的应用程序。来自其他应用程序(在其他域中)的内容使用iframe显示。

我如何调整iframes的大小以适应iframes的内容的高度?

我试图破译的javascript谷歌使用,但它是模糊的,搜索网络至今一无所获。

更新:请注意,内容是从其他域加载的,因此适用同源策略。


当前回答

David Bradshaw和Chris Jacob已经建议使用postMessage方法。我完全同意,做这些事情的正确方法。

我只是想发布一个例子,真实的代码,以防它对一些人来说是现成的答案。

在iframed面:

<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中有一个bug,但不管怎样,让它存在吧。

在父文档端:

<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>

希望对大家有用。

其他回答

下面是一个简单的解决方案,使用与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呈现内容的尺寸。

如果你不需要处理来自不同域的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>

David Bradshaw和Chris Jacob已经建议使用postMessage方法。我完全同意,做这些事情的正确方法。

我只是想发布一个例子,真实的代码,以防它对一些人来说是现成的答案。

在iframed面:

<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中有一个bug,但不管怎样,让它存在吧。

在父文档端:

<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>

希望对大家有用。

找不到能完美处理大文本+大图像的东西,但我最终得到了这个,似乎这是对的,或者几乎是对的,每一次:

    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);
    });

这个答案只适用于使用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