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

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

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

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


当前回答

使用jQuery:

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

其他回答

我正在实现ConroyP的帧中帧解决方案,以取代基于设置文档的解决方案。域,但发现它是相当困难的确定iframe的内容的高度在不同的浏览器(测试与FF11, Ch17和IE9现在)。

ConroyP uses:

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

代码没有优化,这是从我的devel测试:)

希望有人觉得这有用!

最后,我找到了一些其他的解决方案,从iframe使用窗口发送数据到父网站。postMessage(消息、targetOrigin);。下面我来解释一下我是怎么做到的。

站点A = http://foo.com 站点B = http://bar.com

sitb在网站内部加载

SiteB网站有这条线

window.parent.postMessage("Hello From IFrame", "*"); 

or

window.parent.postMessage("Hello From IFrame", "http://foo.com");

然后site ea有如下代码

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

如果你想添加安全连接,你可以在事件输入中使用这个If条件(messageEvent, function (e) {})

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

我相信这样的做法会奏效。

parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;

在iframe内容中加载你的body。

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

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

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