我正在开发类似iGoogle的应用程序 . 来自其他应用程序(在其他域上)的内容使用iframe显示 .
如何调整iframe的大小以适应iframe内容的高度?
我试图破译谷歌使用的javascript,但是它被混淆了,到目前为止搜索网络已经没有结果 .
Update: 请注意,内容是从其他域加载的,因此same-origin policy适用 .
我正在开发类似iGoogle的应用程序 . 来自其他应用程序(在其他域上)的内容使用iframe显示 .
如何调整iframe的大小以适应iframe内容的高度?
我试图破译谷歌使用的javascript,但是它被混淆了,到目前为止搜索网络已经没有结果 .
Update: 请注意,内容是从其他域加载的,因此same-origin policy适用 .
20 回答
此答案仅适用于使用Bootstrap的网站 . Bootstrap的响应式嵌入功能完成了这项工作 . 它基于内容的宽度(而不是高度) .
jsfiddle:http://jsfiddle.net/00qggsjj/2/
http://getbootstrap.com/components/#responsive-embed
我们遇到了这种类型的问题,但与您的情况略有相反 - 我们将iframed内容提供给其他域上的网站,因此same origin policy也是一个问题 . 经过长达数小时的拖网搜索后,我们最终找到了一个(有点......)可行的解决方案,您可以根据自己的需要进行调整 .
围绕相同的原始策略有一种方法,但它需要对iframed内容和框架页面进行更改,因此如果您无法双方请求更改,则此方法对您来说不是很有用,我耽心 .
有一个浏览器怪癖,它允许我们绕过相同的原始政策 - javascript可以与其自己的域上的页面进行通信,也可以与已经有iframed的页面进行通信,但从不与其进行框架化的页面进行通信,例如,如果你有:
然后
home.html
可以与framed.html
(iframed)和helper.html
(同一域)进行通信 .framed.html
可以发送消息到helper.html
(iframed)但不能发送home.html
(子节点不能与父节点进行跨域通信) .这里的关键是
helper.html
可以从framed.html
接收消息,而 can also communicate 可以接收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
There's an explanation here facebook如何处理它,这可能比我的上面稍微清楚一点!
Code
在
www.foo.com/home.html
中,需要以下javascript代码(这可以从任何域上的.js文件加载,顺便提一下......):在
www.bar.net/framed.html
:www.foo.com/helper.html
的内容:这有点棘手,因为您必须知道iframe页面何时加载,这在您无法控制其内容时会很困难 . 它可以为iframe添加一个onload处理程序,但我在过去尝试过它,它在浏览器中的行为有很大不同(不要猜猜谁最烦人......) . 您可能必须向执行调整大小的iframe页面添加一个函数,并将一些脚本注入到侦听加载事件或调整事件大小的内容中,然后调用前一个函数 . 我正在考虑为页面添加一个函数,因为你想确保它的安全,但我不知道它会有多容易 .
http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html上的解决方案效果很好(使用jQuery):
我不知道你需要增加30个长度...... 1对我有用 .
FYI :如果您的iFrame上已经有"height"属性,则只需添加style = "height: xxx" . 这可能不是你想要的 .
可能有点晚了,因为所有其他答案都比较旧:-)但是......这是我的解决方案 . 在实际的FF,Chrome和Safari 5.0中测试过 .
CSS:
JavaScript的:
希望这会对任何人有所帮助 .
这里's a jQuery approach that adds the info in json via the src attribute of the iframe. Here'是一个演示,调整大小并滚动这个窗口..带有json的结果url看起来像这样...... http://fiddle.jshell.net/zippyskippy/RJN3G/show/#{docHeight:5124,windowHeight:1019,scrollHeight:571}#
这是源代码小提琴http://jsfiddle.net/zippyskippy/RJN3G/
获取iframe内容高度然后将其提供给此iframe
这个我相信的东西应该工作 .
在iframe内容中加载您的身体onload .
https://developer.mozilla.org/en/DOM/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/
使用jQuery的最简单方法:
iGoogle小工具必须积极实施调整大小,因此我的猜测是在跨域模型中,如果没有远程内容以某种方式参与,则无法执行此操作 . 如果您的内容可以使用典型的跨域通信技术将具有新大小的消息发送到容器页面,那么其余的很简单 .
我有一个简单的解决方案,并要求您确定链接的宽度和高度,请尝试(它适用于大多数浏览器):
在加载时使用jquery(跨浏览器):
在响应式页面中调整大小:
使用jQuery:
parent.html
child.html
如果您不需要处理来自不同域的iframe内容,请尝试使用此代码,它将完全解决问题并且很简单:
我正在实施ConroyP的框架帧解决方案来替换基于设置document.domain的解决方案,但发现在不同的浏览器中正确确定iframe内容的高度非常困难(现在用FF11,Ch17和IE9进行测试) ) .
ConroyP使用:
但这只适用于初始页面加载 . 我的iframe有动态内容,我需要在某些事件上调整iframe的大小 .
我最终做的是为不同的浏览器使用不同的JS属性 .
getBrowserData()是Ext Core的http://docs.sencha.com/core/source/Ext.html#method-Ext-apply的浏览器检测功能"inspired"
这适用于FF和IE,但后来Chrome出现了问题 . 其中一个是计时问题,显然需要Chrome一段时间来设置/检测iframe的高度 . 如果iframe高于内容,则Chrome也不会正确返回iframe中内容的高度 . 当高度降低时,这不适用于动态内容 .
为了解决这个问题,我总是在检测内容的高度之前将iframe设置为较低的高度,然后将iframe高度设置为正确的值 .
代码没有优化,它来自我的开发测试:)
希望有人觉得这很有帮助!
这是一个使用动态生成的样式表的简单解决方案,该样式表由与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的呈现内容的维度 .
如果要缩小网页以使其适合iframe大小:
您应该调整 iframe 的大小以使其适合内容
然后你应该用加载的网页内容缩小整个iframe
这是一个例子:
最后,我找到了一些其他解决方案,使用
window.postMessage(message, targetOrigin);
从iframe向父网站发送数据 . 在这里,我解释我是如何做的 .网站A = http://foo.com网站B = http://bar.com
SiteB正在siteA网站内加载
SiteB网站有这条线
要么
然后siteA有以下代码
如果要添加安全连接,可以在
eventer(messageEvent, function (e) {})
中使用此条件For IE
内部IFrame:
外: