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

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

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

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


当前回答

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

希望这对大家有所帮助。

其他回答

使用jquery加载(跨浏览器):

 <iframe src="your_url" marginwidth="0"  marginheight="0" scrolling="No" frameborder="0"  hspace="0" vspace="0" id="containiframe" onload="loaderIframe();" height="100%"  width="100%"></iframe>

function loaderIframe(){
var heightIframe = $('#containiframe').contents().find('body').height();
$('#frame').css("height", heightFrame);
 }  

在响应式页面中调整大小:

$(window).resize(function(){
if($('#containiframe').length !== 0) {
var heightIframe = $('#containiframe').contents().find('body').height();
 $('#frame').css("height", heightFrame);
}
});

This is slightly tricky as you have to know when the iframe page has loaded, which is difficuly when you're not in control of its content. Its possible to add an onload handler to the iframe, but I've tried this in the past and it has vastly different behaviour across browsers (not guess who's the most annoying...). You'd probably have to add a function to the iframe page that performs the resize and inject some script into the content that either listens to load events or resize events, which then calls the previous function. I'm thinking add a function to the page since you want to make sure its secure, but I have no idea how easy it will be to do.

我在这里读了很多答案,但几乎每个人都给出了一些交叉起源的框架块。

错误示例:

未捕获的DOMException:阻止了一个原点为“null”的帧 访问跨原点框架。

在相关线程中的答案也是一样的:

使iframe自动调整高度根据内容而不使用滚动条?

我不想使用第三方库,如iFrame Resizer或类似的库。

来自@ChrisJacob的答案很接近,但我缺少一个完整的工作示例,而不仅仅是链接。@Selvamani和@latitov也是很好的互补。

https://stackoverflow.com/a/3219970/3850405

我使用width="100%"的iframe,但代码可以修改为宽度以及工作。

这是我如何解决设置自定义高度的iframe:

iframe嵌入:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="description"
          content="Web site" />
    <title>Test with embedded iframe</title>
</head>
<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <iframe id="ifrm" src="https://localhost:44335/package/details?key=123" width="100%"></iframe>
    <script type="text/javascript">
        window.addEventListener('message', receiveMessage, false);

        function receiveMessage(evt) {
            console.log("Got message: " + JSON.stringify(evt.data) + " from origin: " + evt.origin);
            // Do we trust the sender of this message?
            if (evt.origin !== "https://localhost:44335") {
                return;
            }

            if (evt.data.type === "frame-resized") {
                document.getElementById("ifrm").style.height = evt.data.value + "px";
            }
        }
    </script>
</body>
</html>

iframe源代码,示例来自创建React应用程序,但只使用HTML和JS。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="description"
          content="Web site created using create-react-app" />
    <title>React App</title>
</head>
<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script type="text/javascript">
        //Don't run unless in an iframe
        if (self !== top) {
            var rootHeight;
            setInterval(function () {
                var rootElement = document.getElementById("root");
                if (rootElement) {
                    var currentRootHeight = rootElement.offsetHeight;
                    //Only send values if height has changed since last time
                    if (rootHeight !== currentRootHeight) {
                        //postMessage to set iframe height
                        window.parent.postMessage({ "type": "frame-resized", "value": currentRootHeight }, '*');
                        rootHeight = currentRootHeight;
                    }
                }
            }
                , 1000);
        }
    </script>
</body>
</html>

带有setInterval的代码当然可以修改,但它与动态内容一起工作得非常好。setInterval仅在内容嵌入iframe时激活,postMessage仅在高度改变时发送消息。

你可以在这里阅读更多关于Window.postMessage()的内容,但描述非常适合我们想要实现的目标:

The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it. Normally, scripts on different pages are allowed to access each other if and only if the pages they originate from share the same protocol, port number, and host (also known as the "same-origin policy"). window.postMessage() provides a controlled mechanism to securely circumvent this restriction (if used properly).

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

我有一个简单的解决方案,需要你确定链接的宽度和高度,请尝试(它适用于大多数浏览器):

<a href='#' onClick=" document.getElementById('myform').src='t2.htm';document.getElementById('myform').width='500px'; document.getElementById('myform').height='400px'; return false">500x400</a>

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/