根据内容调整iframe的大小

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

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

我试图破译Google使用的JavaScript,但它被混淆了,并且搜索网页到目前为止一直没有成果。

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


我们遇到了这种类型的问题,但与您的情况稍有相反 - 我们正在向其他域中的站点提供iframed内容,因此同一起源策略也是一个问题。 经过几个小时的谷歌搜索后,我们终于找到了一个(稍微有点)可行的解决方案,您可以根据自己的需求进行调整。

围绕同一个来源策略有一种解决方法,但它需要在iframed内容和成帧页面上进行更改,所以如果您无法在两侧请求更改,则此方法对您而言不会有用,恐怕。

有一个浏览器的怪癖,它允许我们摆脱相同的原产地政策 - javascript可以与页面在自己的域名,或与它有iframed页面,但从来没有页面框架,例如,如果你有:

 www.foo.com/home.html, which iframes
 |-> www.bar.net/framed.html, which iframes
     |-> www.foo.com/helper.html

那么home.html可以与framed.htmlframed.html )和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可以发送消息给helper.htmlhelper.html )但不是home.html (孩子不能与父母交流域名)。

这里的关键是helper.html可以接收来自framed.html消息,并且还可以home.html 通信

所以基本上,当framed.html加载时,它会自动调整高度,告诉helper.html ,它将消息传递给home.html ,然后可以调整framed.html所在的iframe的大小。

我们发现将消息从framed.html传递给helper.html最简单的方法是通过URL参数。 为此, framed.html有一个指定了src=''的iframe。 当onload激发时,它会评估自身的高度,并将iframe的src设置为helper.html?height=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>

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

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

window.postMessage()

window.postMessage是一种安全启用跨源通信的方法。 通常情况下,只有当执行它们的页面位于具有相同协议(通常都是http),端口号(80是http的缺省值)和主机(模数)的位置时,才允许不同页面上的脚本访问对方document.domain被两个页面设置为相同的值)。 window.postMessage提供了一种受控机制,以正确使用时的安全方式规避此限制。

概要

调用window.postMessage时,当任何必须执行的待处理脚本完成时(例如,如果事件处理程序调用了window.postMessage,之前设置的暂挂超时等,则剩余的事件处理程序),将在目标窗口上分派MessageEvent。 )。 MessageEvent具有类型消息,它是一个数据属性,它被设置为提供给window.postMessage的第一个参数的字符串值,该属性对应于窗口中主文档来源的时间窗口window.postMessage。 postMessage被调用,并且一个source属性是window.postMessage被调用的窗口。 (事件的其他标准特性与预期值一起出现。)

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

准系统的例子...

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

window.postMessage上的HTML 5工作草案

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

John Resig关于跨窗口消息传递

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

链接地址: http://www.djcxy.com/p/19245.html

上一篇: Resizing an iframe based on content

下一篇: Remove border from IFrame