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

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

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

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


当前回答

使用jQuery的最简单方法:

$("iframe")
.attr({"scrolling": "no", "src":"http://www.someotherlink.com/"})
.load(function() {
    $(this).css("height", $(this).contents().height() + "px");
});

其他回答

可能有点晚了,因为所有其他的答案都是老的:-)但是…这是我的解决方案。在实际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
        });
    });
});

希望这对大家有所帮助。

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/

https://getbootstrap.com/docs/4.0/utilities/embed/

经过大量的研究,我明白了,这不是一个独特的问题,我打赌Bootstrap处理它。你瞧……

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

我们有这种类型的问题,但稍微与您的情况相反-我们正在向其他域的网站提供iframed内容,因此同源策略也是一个问题。在花了好几个小时搜索谷歌后,我们最终找到了一个(有点..)可行的解决方案,您可能能够适应您的需求。

有一种方法可以绕过同源策略,但它需要同时对iframe内容和框架页面进行更改,因此,如果您不能同时请求更改两边的内容,那么这种方法恐怕对您没有多大用处。

有一个浏览器的怪癖,它允许我们绕过同源策略——javascript可以与自己域中的页面通信,也可以与它已经框架的页面通信,但不能与它被框架的页面通信,例如,如果你有:

 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可以向help .html (iframed)发送消息,但不能向home.html发送消息(子节点不能与父节点跨域通信)。

这里的关键是help .html可以接收来自framed.html的消息,也可以与home.html通信。

本质上,当framed。html加载时,它计算出自己的高度,告诉helper。html,后者将消息传递给home。html,后者可以调整framed。html所在的iframe的大小。

我们发现的将消息从framed.html传递到help .html的最简单方法是通过URL参数。为此,frames .html有一个iframe,并指定了src= "。当它的onload触发时,它计算自己的高度,并在此时将iframe的src设置为help .html?身高= N

这里有一个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>