我正在开发一个类似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>

希望对大家有用。

其他回答

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

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

在iframe内容中加载你的body。

最后,我找到了一些其他的解决方案,从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);

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

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