当内容更改时的iframe高度问题
当内容更改时的iframe高度问题
我正在一个iframe中加载一个aspx网页。Iframe中的内容可能比iframe的高度更高。Iframe不应该有滚动条。\n我在iframe内部有一个包装的div标签,基本上就是所有的内容。我写了一些jQuery代码来实现调整大小:\n$(\"#TB_window\", window.parent.document).height($(\"body\").height() + 50);\n其中\nTB_window是包含Iframe的div。\nbody是iframe中aspx网页的body标签。\n这个脚本被附加到iframe内容上。在Chrome上运行良好,但是在Firefox上,TB_window会折叠。我对此感到非常困惑和迷失。
问题出现的原因:
问题出现的原因是在使用iframe嵌套页面时,当内容发生变化时,iframe的高度无法自动调整。
解决方法:
根据我发现的解决方法,我发现接受的答案并不够,因为Safari或Chrome不支持X-FRAME-OPTIONS: Allow-From。所以我选择了另一种方法,这个方法是在Disqus的Ben Vinegar的演示中找到的。这个方法的思路是在父窗口添加一个事件监听器,然后在iframe内部使用window.postMessage发送一个事件给父窗口,告诉它做某事(调整iframe的大小)。
首先,在父文档中添加一个事件监听器:
window.addEventListener('message', function(e) { var $iframe = jQuery("#myIframe"); var eventName = e.data[0]; var data = e.data[1]; switch(eventName) { case 'setHeight': $iframe.height(data); break; } }, false);
然后,在iframe内部编写一个函数来发送消息:
function resize() { var height = document.getElementsByTagName("html")[0].scrollHeight; parent.postMessage(["setHeight", height], "*"); }
最后,在iframe内部的body标签上添加一个onLoad事件,触发resize函数:
为了让这个方法对我起作用,我不得不将"window.parent"更改为"parent"。
不错!但它只会加载一次高度。如果你想要使iframe真正响应式,我建议每隔一秒调用一次resize方法,像这样:
setInterval(resize, 1000);
这个解决方法很好,并且没有跨站脚本错误。
当内容发生变化时,iframe的高度问题可能会出现。这个问题的原因是,当内容发生变化时,iframe的高度没有自动调整,导致内容无法完全显示。为了解决这个问题,可以使用以下方法:
1. 在iframe中添加一个onload事件,调用resizeIframe函数来调整iframe的高度。
<iframe onload="resizeIframe(this)" ...
2. 在resizeIframe函数中,获取iframe中内容的高度,并将iframe的高度设置为内容高度加上一定的像素值。这样可以确保iframe的高度能够容纳所有内容。
function resizeIframe(iframe) { var size = iframe.contentWindow.document.body.scrollHeight; var size_new = size + 20; iframe.height = size_new + "px"; }
3. 如果内容经常发生变化,可以在内容更新后调用parent.resizeIframe(this.frameElement)来重新调整iframe的高度。
parent.resizeIframe(this.frameElement);
4. 如果内容的大小经常变化,并且iframe设计用于放置在与加载页面不同的域中,则需要使用postMessage和receiveMessage来解决这个问题。可以使用第三方库github.com/jeffomatic/nojquery-postmessage来实现这个功能。具体做法是计算新的高度,并将消息发送给父级框架,父级框架根据接收到的消息来调整iframe的高度。
5. 如果需要在内容发生变化时自动调整iframe的高度,可以使用定时器来定期检测内容的变化,并调用resizeIframe函数来重新调整iframe的高度。
6. 在resizeIframe函数中,如果需要将iframe的高度调整为小于当前高度的值,需要在重新赋值之前将iframe的高度设置为空字符串。这是因为iframe.contentWindow.document.body.scrollHeight只有在iframe的高度小于所需内容高度时才准确。
7. 如果希望在加载时隐藏iframe的滚动条并获取高度,可以在resizeIframe函数中添加以下代码:
iframe.height = iframe.contentWindow.document.body.scrollHeight + "px"; iframe.contentWindow.document.querySelector("html").style.overflow = "hidden";
8. 如果遇到跨域问题,可能会出现"Permission denied to access property 'document' on cross-origin object"的错误。此时需要处理跨域访问的权限问题。
当内容发生变化时,iframe
的高度会出现问题。解决方法是通过以下步骤获取iframe
内容的高度:
1. 使用contentWindow.document.body.scrollHeight
获取iframe
内容的高度。
2. 在iframe
加载后,通过以下步骤更改高度:
<script type="text/javascript"> function iframeLoaded() { var iFrameID = document.getElementById('idIframe'); if(iFrameID) { // 先删除高度,然后重新设置高度 iFrameID.height = ""; iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px"; } } </script>
3. 在iframe
标签上,使用onload="iframeLoaded()"
来绑定事件处理程序:
<iframe id="idIframe" onload="iframeLoaded()" ...
4. 在iframe
的内容脚本中,如果在表单提交后需要从iframe
本身调用iframeLoaded
,可以通过以下步骤实现:
parent.iframeLoaded();
该解决方法不支持跨域。
跨域与此代码无关。有一个安全问题需要通过命令来绕过。
可以通过添加以下行来查找X-FRAME-OPTIONS
: Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
或 response.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
这样解决了跨域iframe
大小问题:github.com/davidjbradshaw/iframe-resizer。
你的脚本很好用,甚至可能支持跨域,但最常用的CORS场景是在无法访问远程加载页面的情况下。我试过将你的脚本用于将Google Docs表单嵌入网站,但却不起作用;(