调整iframe的宽度和高度以适应其中的内容

Sto*_*art 281 html javascript iframe adjustment

我需要一个解决方案自动调节widthheight一个iframe勉强适合其内容.关键是iframe加载后可以更改宽度和高度.我想我需要一个事件动作来处理iframe中包含的主体尺寸的变化.

Ahm*_*hmy 261

<script type="application/javascript">

function resizeIFrameToFitContent( iFrame ) {

    iFrame.width  = iFrame.contentWindow.document.body.scrollWidth;
    iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
}

window.addEventListener('DOMContentLoaded', function(e) {

    var iFrame = document.getElementById( 'iFrame1' );
    resizeIFrameToFitContent( iFrame );

    // or, to resize all iframes:
    var iframes = document.querySelectorAll("iframe");
    for( var i = 0; i < iframes.length; i++) {
        resizeIFrameToFitContent( iframes[i] );
    }
} );

</script>

<iframe src="usagelogs/default.aspx" id="iFrame1"></iframe>
Run Code Online (Sandbox Code Playgroud)

  • 另外不要忘记它不是跨域.它得到一种_Error的原因:如果域不同,则拒绝访问属性'document'的权限.可以找到解决方案[这里](http://css-tricks.com/cross-domain-iframe-resizing/) (55认同)
  • if(document.getElementById)有什么用? (30认同)
  • 条件不仅无用,而且在极少数情况下,它的目的是保证会引起问题.你为什么要检查一个方法是否存在,然后在检查之外使用方法? (15认同)
  • @StoneHeart:是的,它是跨浏览器.由于contentWindow属性(在DOM规范中未定义),因此代码是非标准兼容的.在DOM规范中存在名为contentDocument的属性,但Internet Explorer 6(和7?)不支持它.可以使用contentWindow属性,它可以在所有常见的浏览器(Gecko,Opera,Webkit,IE)中实现. (8认同)
  • 我认为你的意思是`DOMContentLoaded`,因为`DOMContentReady`似乎不是一件事:https://developer.mozilla.org/en-US/search?q=domcontentready&topic=apps&topic=html&topic=css&topic=js&topic=api&topic = Webdev的 (6认同)
  • 不符合标准,但到目前为止最简单的方法. (3认同)
  • 对于IE9,请尝试`frame.style.height =(newheight)+"px"`和`frame.style.width =(newwidth)+"px";` (3认同)
  • 该解决方案或下面的解决方案在当今的任何浏览器中都不起作用。 (3认同)
  • 如果您不需要支持较旧的浏览器,则在两个窗口之间发送消息可能是一种更清洁的解决方案:http://stackoverflow.com/questions/5606920/cross-domain-iframe-resizer/6940531#6940531 (2认同)

FFi*_*ish 45

跨浏览器的jQuery插件.

Cross-bowser,跨域,用于mutationObserver将iFrame大小保持为内容并postMessage在iFrame和主机页面之间进行通信.使用或不使用jQuery.

  • iframe-resizer库是最可靠的解决方案。 (2认同)

Gar*_*aph 34

到目前为止给出的所有解决方案仅考虑一次性调整大小.您提到您希望能够在修改内容后调整iFrame的大小.为了做到这一点,你需要在iFrame中执行一个函数(一旦内容被更改,你需要触发一个事件来说明内容已经改变).

我被困了一段时间,因为iFrame中的代码似乎仅限于iFrame中的DOM(并且无法编辑iFrame),并且在iFrame外部执行的代码被困在iFrame外部的DOM(并且没有'拿起来自iFrame内部的活动).

解决方案来自于发现(通过同事的帮助)可以告诉jQuery使用什么DOM.在这种情况下,父窗口的DOM.

因此,像这样的代码可以满足您的需求(在iFrame中运行时):

<script type="text/javascript">
    jQuery(document).ready(function () {
        jQuery("#IDofControlFiringResizeEvent").click(function () {
            var frame = $('#IDofiframeInMainWindow', window.parent.document);
            var height = jQuery("#IDofContainerInsideiFrame").height();
            frame.height(height + 15);
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

  • 如果iframe中的父文档和文档都来自同一个域***,这可以很好地工作***.如果它们不是(或者,在chrome中,[如果它们都是本地文件](http://stackoverflow.com/questions/19462608/)),则浏览器的"相同来源"安全策略启动并且它可以防止修改父文档的iframe内容. (12认同)
  • 如何自动触发事件而不是`jQuery("#IDofControlFiringResizeEvent").click(function()`? (2认同)

Guy*_*Guy 29

用于嵌入的单层解决方案:以最小尺寸开始并增加到内容大小.不需要脚本标签.

<iframe src="http://URL_HERE.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>
Run Code Online (Sandbox Code Playgroud)

  • 它不是跨域的。也许服务器需要向框架页面添加一些标题? (5认同)
  • 该解决方案或上述解决方案在当今的任何浏览器中都不起作用。 (4认同)
  • 这里提到“scrollHeight/scrollWidth”的所有答案都应该稍微调整以考虑正文边距。浏览器对文档的 body 元素应用默认的非零边距(它也适用于加载到框架中的内容)。我找到的工作解决方案是添加以下内容:`parseInt(window.getCompulatedStyle(this.contentDocument.body).margin`。 (2认同)

bre*_*njt 23

如果iframe内容来自同一个域,那么这应该很有用.它确实需要jQuery.

$('#iframe_id').load(function () {
    $(this).height($(this).contents().height());
    $(this).width($(this).contents().width());
});
Run Code Online (Sandbox Code Playgroud)

要让它动态调整大小,您可以这样做:

<script language="javaScript">
<!--
function autoResize(){
    $('#themeframe').height($('#themeframe').contents().height());
}
//-->
</script>
<iframe id="themeframe" onLoad="autoResize();" marginheight="0" frameborder="0" src="URL"></iframe>
Run Code Online (Sandbox Code Playgroud)

然后在iframe加载的页面上添加:

<script language="javaScript">
function resize()
{
    window.parent.autoResize();
}

$(window).on('resize', resize);
</script>
Run Code Online (Sandbox Code Playgroud)


Tim*_*imo 15

如果您不想使用jQuery,这是一个跨浏览器的解决方案:

/**
 * Resizes the given iFrame width so it fits its content
 * @param e The iframe to resize
 */
function resizeIframeWidth(e){
    // Set width of iframe according to its content
    if (e.Document && e.Document.body.scrollWidth) //ie5+ syntax
        e.width = e.contentWindow.document.body.scrollWidth;
    else if (e.contentDocument && e.contentDocument.body.scrollWidth) //ns6+ & opera syntax
        e.width = e.contentDocument.body.scrollWidth + 35;
    else (e.contentDocument && e.contentDocument.body.offsetWidth) //standards compliant syntax – ie8
        e.width = e.contentDocument.body.offsetWidth + 35;
}
Run Code Online (Sandbox Code Playgroud)


bbo*_*flo 9

语境

我必须在网络扩展的上下文中自己完成此操作。此 Web 扩展将一些 UI 注入到每个页面中,并且此 UI 位于iframe. 里面的内容iframe是动态的,所以我必须重新调整它iframe本身的宽度和高度。

我使用React,但这个概念适用于每个库。

我的解决方案(假设您同时控制页面和 iframe)

在里面iframe我改变了body样式以具有非常大的尺寸。这将允许内部元素使用所有必要的空间进行布局。制作widthand height100% 对我不起作用(我猜是因为 iframe 有一个默认的width = 300pxand height = 150px

/* something like this */
body {
  width: 99999px;
  height: 99999px;
}
Run Code Online (Sandbox Code Playgroud)

然后我将所有 iframe UI 注入到 div 中并给它一些样式

#ui-root {
  display: 'inline-block';     
}
Run Code Online (Sandbox Code Playgroud)

在其中渲染我的应用程序后#ui-root(在React中我在里面执行此操作componentDidMount),我计算此 div 的尺寸并使用以下方法将它们同步到父页面window.postMessage

let elRect = el.getBoundingClientRect()
window.parent.postMessage({
  type: 'resize-iframe',
  payload: {
    width: elRect.width,
    height: elRect.height
  }
}, '*')
Run Code Online (Sandbox Code Playgroud)

在父框架中我做了这样的事情:

window.addEventListener('message', (ev) => {
  if(ev.data.type && ev.data.type === 'resize-iframe') {
    iframe.style.width = ev.data.payload.width + 'px'
    iframe.style.height = ev.data.payload.height + 'px'
  }
}, false)
Run Code Online (Sandbox Code Playgroud)


pet*_*riq 8

我正在使用此代码在页面上加载时自动调整所有iframe(使用类autoHeight)的高度.经过测试,适用于IE,FF,Chrome,Safari和Opera.

function doIframe() {
    var $iframes = $("iframe.autoHeight"); 
    $iframes.each(function() {
        var iframe = this;
        $(iframe).load(function() {
            setHeight(iframe);
        });
    });
}

function setHeight(e) {
  e.height = e.contentWindow.document.body.scrollHeight + 35;
}

$(window).load(function() {
    doIframe();
});
Run Code Online (Sandbox Code Playgroud)

  • 我认为35只是滚动条的厚度 (3认同)
  • 你要添加的神奇之处是什么?您使用哪种浏览器和操作系统进行测量? (2认同)

Adr*_* P. 8

在我尝试了地球上的一切之后,这对我来说真的很有用.

的index.html

<style type="text/css">
html, body{
  width:100%;
  height:100%;
  overflow:hidden;
  margin:0px;   
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function autoResize(iframe) {
    $(iframe).height($(iframe).contents().find('html').height());
}
</script>

<iframe src="http://iframe.domain.com" width="100%" height="100%" marginheight="0" frameborder="0" border="0" scrolling="auto" onload="autoResize(this);"></iframe>
Run Code Online (Sandbox Code Playgroud)

  • @Michael Rogers 与 $ 存在冲突,或者您忘记包含 jQuery.js 文件。使用通用函数 /sf/ask/427689321/ 或用 jQuery 替换 $ (2认同)

Mas*_*Mas 5

这是一个可靠的解决方案

function resizer(id)
{

var doc=document.getElementById(id).contentWindow.document;
var body_ = doc.body, html_ = doc.documentElement;

var height = Math.max( body_.scrollHeight, body_.offsetHeight, html_.clientHeight, html_.scrollHeight, html_.offsetHeight );
var width  = Math.max( body_.scrollWidth, body_.offsetWidth, html_.clientWidth, html_.scrollWidth, html_.offsetWidth );

document.getElementById(id).style.height=height;
document.getElementById(id).style.width=width;

}
Run Code Online (Sandbox Code Playgroud)

HTML

<IFRAME SRC="blah.php" id="iframe1"  onLoad="resizer('iframe1');"></iframe>
Run Code Online (Sandbox Code Playgroud)