javascript - react - 设置iframe高度




根据内容调整iframe的大小 (14)

获取iframe内容高度然后将其提供给此iframe

 var iframes = document.getElementsByTagName("iframe");
 for(var i = 0, len = iframes.length; i<len; i++){
      window.frames[i].onload = function(_i){
           return function(){
                     iframes[_i].style.height = window.frames[_i].document.body.scrollHeight + "px";
                     }
      }(i);
 }

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

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

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

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


iGoogle小工具必须积极实施调整大小,因此我的猜测是在跨域模型中,如果没有以某种方式参与远程内容,则无法做到这一点。 如果您的内容可以使用典型的跨域通信技术将具有新大小的消息发送到容器页面,则其余部分很简单。


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/


下面是一个简单的解决方案,它使用与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的渲染内容的尺寸。


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

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

希望这会帮助任何人。


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

当您想缩小网页以适应iframe大小时:

  1. 您应该调整iframe以适应内容
  2. 然后你应该用加载的网页内容缩小整个iframe

这里是一个例子:

<div id="wrap">
   <IFRAME ID="frame" name="Main" src ="http://www.google.com" />
</div>
<style type="text/css">
    #wrap { width: 130px; height: 130px; padding: 0; overflow: hidden; }
    #frame { width: 900px; height: 600px; border: 1px solid black; }
    #frame { zoom:0.15; -moz-transform:scale(0.15);-moz-transform-origin: 0 0; }
</style>

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

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

我正在实施ConroyP的框架框架解决方案,以取代基于设置document.domain的解决方案,但发现很难在不同浏览器中正确确定iframe内容的高度(现在使用FF11,Ch17和IE9进行测试)。

ConroyP使用:

var height = document.body.scrollHeight;

但是,这只适用于初始页面加载。 我的iframe具有动态内容,我需要在某些事件上调整iframe的大小。

我最终做的是为不同的浏览器使用不同的JS属性。

function getDim () {
    var body = document.body,
        html = document.documentElement;

    var bc = body.clientHeight;
    var bo = body.offsetHeight;
    var bs = body.scrollHeight;
    var hc = html.clientHeight;
    var ho = html.offsetHeight;
    var hs = html.scrollHeight;

    var h = Math.max(bc, bo, bs, hc, hs, ho);

    var bd = getBrowserData();

    // Select height property to use depending on browser
    if (bd.isGecko) {
        // FF 11
        h = hc;
    } else if (bd.isChrome) {
        // CH 17
        h = hc;
    } else if (bd.isIE) {
        // IE 9
        h = bs;
    }

    return h;
}

getBrowserData()是由Ext Core的http://docs.sencha.com/core/source/Ext.html#method-Ext-apply “启发”的浏览器检测函数

这对FF和IE运行良好,但随后出现了Chrome的问题。 其中一个是计时问题,显然需要Chrome一段时间来设置/检测iframe的高度。 然后,如果iframe高于内容,Chrome也不会正确返回iframe中内容的高度。 当高度降低时,这不适用于动态内容。

为了解决这个问题,我总是将iframe设置为较低的高度,然后检测内容的高度,然后将iframe的高度设置为正确的值。

function resize () {
    // Reset the iframes height to a low value.
    // Otherwise Chrome won't detect the content height of the iframe.
    setIframeHeight(150);

    // Delay getting the dimensions because Chrome needs
    // a few moments to get the correct height.
    setTimeout("getDimAndResize()", 100);
}

代码没有优化,它来自我的devel测试:)

希望有人认为这有帮助!



这个我相信的东西应该工作。

parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;

在iframe内容上加载你的body。


这里有一个jQuery方法,通过iframe的src属性在json中添加信息。 这里是一个演示,调整大小和滚动此窗口..与json产生的网址看起来像这样... http://fiddle.jshell.net/zippyskippy/RJN3G/show/#{docHeight:5124,windowHeight:1019,scrollHeight:571}#

这里是源代码小提琴http://jsfiddle.net/zippyskippy/RJN3G/

function updateLocation(){

    var loc = window.location.href;
    window.location.href = loc.replace(/#{.*}#/,"") 
        + "#{docHeight:"+$(document).height() 
        + ",windowHeight:"+$(window).height()
        + ",scrollHeight:"+$(window).scrollTop()
        +"}#";

};

//setInterval(updateLocation,500);

$(window).resize(updateLocation);
$(window).scroll(updateLocation);

<html>
<head>
<script>
function frameSize(id){
var frameHeight;

document.getElementById(id).height=0 + "px";
if(document.getElementById){
    newheight=document.getElementById(id).contentWindow.document.body.scrollHeight;    
}

document.getElementById(id).height= (frameHeight) + "px";
}
</script>
</head>

<body>

<iframe id="frame"  src="startframe.html" frameborder="0" marginheight="0" hspace=20     width="100%" 

onload="javascript:frameSize('frame');">

<p>This will work, but you need to host it on an http server, you can do it locally.    </p>
</body>
</html>




widget