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

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

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

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


当前回答

https://developer.mozilla.org/en/DOM/window.postMessage

window.postMessage() window.postMessage is a method for safely enabling cross-origin communication. Normally, scripts on different pages are only allowed to access each other if and only if the pages which executed them are at locations with the same protocol (usually both http), port number (80 being the default for http), and host (modulo document.domain being set by both pages to the same value). window.postMessage provides a controlled mechanism to circumvent this restriction in a way which is secure when properly used. Summary window.postMessage, when called, causes a MessageEvent to be dispatched at the target window when any pending script that must be executed completes (e.g. remaining event handlers if window.postMessage is called from an event handler, previously-set pending timeouts, etc.). The MessageEvent has the type message, a data property which is set to the string value of the first argument provided to window.postMessage, an origin property corresponding to the origin of the main document in the window calling window.postMessage at the time window.postMessage was called, and a source property which is the window from which window.postMessage is called. (Other standard properties of events are present with their expected values.)

iFrame- resizzer库使用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/

Barebones操作...

http://onlineaspect.com/uploads/postmessage/parent.html

HTML 5工作草案在window.postMessage

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

John Resig谈跨窗口消息传递

http://ejohn.org/blog/cross-window-messaging/

其他回答

如果您可以控制iframe内容,我强烈建议使用

调整观察者大小

只需在iframe的srcdoc属性的末尾插入以下内容, 如果需要,可以转义。

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

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呈现内容的尺寸。

下面是一个jQuery方法,它通过iframe的src属性在json中添加信息。这是一个演示,调整大小和滚动这个窗口。使用json生成的url如下所示… http://fiddle.jshell.net/zippyskippy/RJN3G/show/ {scrollHeight windowHeight docHeight: 5124: 1019: 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);
<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>