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


300

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



接受的答案不起作用。试试stackoverflow.com/a/31513163/482382
Steven Shaw,

Answers:


268
<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>

8
@StoneHeart:是的,它是跨浏览器。由于contentWindow属性(DOM规范中未定义),因此该代码不符合标准。在DOM规范中,存在一个称为contentDocument的属性,但是Internet Explorer 6(和7?)不支持该属性。可以改为使用contentWindow属性,并且可以在所有常见的浏览器(Gecko,Opera,Webkit,IE)中实现该属性。
拉斐尔

30
if(document.getElementById)有什么用?
Ally 2012年

55
也不要忘记它不是跨域的。出现某种错误的原因:如果域不同,则拒绝访问属性“文档”的权限。可以在此处
Pierre de LESPINAY,2012年

15
有条件的不仅无用,而且在极少数情况下可以保证会导致问题。为什么要检查是否存在方法,然后在检查之外使用该方法?
JS

6
我觉得你的意思DOMContentLoaded,因为DOMContentReady它似乎没有一件事:developer.mozilla.org/en-US/...
最大Heiber

46

跨浏览器jQuery插件

跨浏览器,跨域,用于mutationObserver使iFrame保持与内容大小相同,并postMessage在iFrame和主机页面之间进行通信。可以使用jQuery,也可以不使用jQuery。


3
iframe-resizer库是最可靠的解决方案。
意志

35

到目前为止,所有给出的解决方案都只能解决一次调整大小的问题。您提到要修改内容后能够调整iFrame的大小。为此,您需要在iFrame中执行一个函数(一旦更改了内容,则需要触发一个事件以说内容已更改)。

我被卡住了一段时间,因为iFrame内的代码似乎仅限于iFrame内的DOM(并且无法编辑iFrame),而在iFrame之外执行的代码与在iFrame之外的DOM卡在一起(并且不能t接收来自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>

完整的代码是什么?我认为脚本会放在iframe html中?
Andrew Hundt 2013年

这是完整的代码,是的,它在iFrame的HTML中运行。“ window.parent.document”部分指定jQuery选择器应使用父文档的DOM,而不是您所在文档(位于iFrame中)的DOM。
Garnaph

13
如果父文档和iframe中的文档都来自同一域,则此方法可以很好地工作。如果不是(或者在chrome中,它们都是本地文件),那么浏览器的“相同来源”安全策略就会生效,并且会阻止iframe内容修改父文档。
user56reinstatemonica8 2014年

1
对于尝试跨域进行此类工作的任何人,请查看window.postMessage(IE8 +),并注意在主机(父)文档和源(iframe)文档中都需要自定义脚本。jQuery postmessage插件可能会有所帮助。由于在主机和源上都需要脚本,因此让主机使用JSON-P通过AJAX加载内容可能会更容易。
user56reinstatemonica8 2014年

3
如何自动触发事件而不是jQuery("#IDofControlFiringResizeEvent").click(function ()
2015年

33

嵌入的单线解决方案:从最小尺寸开始,然后增加到内容尺寸。不需要脚本标签。

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


运行代码段不适用于Safari 9.1.1,可能包含SO问题?
Elensar

它不是跨域的。也许服务器需要向框架页面添加一些标题?
Finesse '18

此处提到的所有答案scrollHeight/scrollWidth都应进行一些调整,以考虑到车身边距。浏览器为文档的body元素应用默认的非零边距(也适用于加载到框架中的内容)。我发现的有效解决方案是添加以下内容:parseInt(window.getComputedStyle(this.contentDocument.body).margin
Stan

24

如果iframe内容来自同一域,则应该会很好用。它确实需要jQuery。

$('#iframe_id').load(function () {
    $(this).height($(this).contents().height());
    $(this).width($(this).contents().width());
});

要动态调整其大小,可以执行以下操作:

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

然后在iframe加载的页面上添加以下内容:

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

$(window).on('resize', resize);
</script>

当来源来自其他域时,是否有任何简单的方法?
BruceJohnJennerLawso'3

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;
}

1
那很奇怪。对我来说,它计算出iframe的宽度很奇怪。内容宽度为750,计算得出为300。您有想法吗?
罗布

我玩过此代码(添加了高度选项)。如果将iFrame高度设置为100%,则它将其限制为200px。如果我将iFrame高度设置为600像素,那么它会坚持下去。@RobertJagoda你有解决办法吗?
iaindownie

9

在我尝试了地球上的所有内容之后,这确实对我有用。

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>

它说:未捕获的TypeError:$不是HTMLIFrameElement.onload((index :: 204)处autoResize((index):200)处的函数)
Michael Rogers

2
@Michael Rogers与$冲突,或者您忘记包含jQuery.js文件。使用通用函数stackoverflow.com/questions/6109847/…或将$替换为jQuery
Adrian P.

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();
});

2
您要添加的此魔力35是什么?您对哪个浏览器和操作系统进行了测量?
h2stein 2012年

现在我真的不知道为什么要添加35像素。但是我可以肯定地说,我已经在FF,IE(7、8、9)和Chrome上对其进行了测试,并且运行良好。
petriq 2012年

3
我认为35只是滚动条的厚度
Sadegh

我必须对其进行一些微调才能使其正常工作-称为setHeight(iframe); 直接(删除$(IFRAME).load()包装它周围。
shacker

添加的不可思议的35个像素要考虑iframe填充。我要补充一点,iframe不应该填充iframe的内容。
菲利普·梅洛

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;

}

HTML

<IFRAME SRC="blah.php" id="iframe1"  onLoad="resizer('iframe1');"></iframe>

3

我在上面稍微修改了Garnaph的出色解决方案。似乎他的解决方案根据事件发生前的大小修改了iframe大小。对于我的情况(通过iframe提交电子邮件),我需要在提交后立即更改iframe的高度。例如,提交后显示验证错误或“谢谢”消息。

我只是消除了嵌套的click()函数,并将其放入我的iframe html中:

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

为我工作,但不确定跨浏览器功能。


3

如果可以同时控制IFRAME内容和父窗口,则需要iFrame Resizer

通过该库,可以自动调整相同和跨域iFrame的高度和宽度的大小,以适合其包含的内容。它提供了一系列功能来解决使用iFrame时最常见的问题,其中包括:

  • 将iFrame调整为内容大小的高度和宽度。
  • 适用于多个和嵌套的iFrame。
  • 跨域iFrame的域身份验证。
  • 提供一系列页面大小计算方法,以支持复杂的CSS布局。
  • 检测对DOM的更改,这些更改可能导致使用MutationObserver调整页面大小。
  • 检测可能导致页面调整大小的事件(“窗口调整大小”,“ CSS动画和过渡”,“方向改变”和“鼠标”事件)。
  • 通过PostMessage在iFrame和主机页面之间简化了消息传递。
  • 修复了iFrame中的页面链接,并支持iFrame和父页面之间的链接。
  • 提供自定义大小和滚动方法。
  • 将父位置和视口大小公开到iFrame。
  • 与ViewerJS一起使用以支持PDF和ODF文档。
  • 后备支持降至IE8。

2

使用上述方法都无法使用。

javascript:

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;

    }

的HTML:

<div style="background-color:#b6ff00;min-height:768px;line-height:inherit;height:inherit;margin:0px;padding:0px;overflow:visible" id="mainDiv"  >
         <input id="txtHeight"/>height     <input id="txtWidth"/>width     
        <iframe src="head.html" name="topFrame" scrolling="No" noresize="noresize" id="topFrame" title="topFrame" style="width:100%; height: 47px" frameborder="0"  ></iframe>
        <iframe src="left.aspx" name="leftFrame" scrolling="yes"   id="Iframe1" title="leftFrame" onload="resizer('Iframe1');" style="top:0px;left:0px;right:0px;bottom:0px;width: 30%; border:none;border-spacing:0px; justify-content:space-around;" ></iframe>
        <iframe src="index.aspx" name="mainFrame" id="Iframe2" title="mainFrame" scrolling="yes" marginheight="0" frameborder="0" style="width: 65%; height:100%; overflow:visible;overflow-x:visible;overflow-y:visible; "  onload="resizer('Iframe2');" ></iframe>
</div>

信封:IE 10,Windows 7 x64


2

经过一些试验,我想出了另一种解决方案。我最初尝试将代码标记为该问题的“最佳答案”,但此方法无效。我的猜测是因为当时我的程序中的iframe是动态生成的。这是我使用的代码(对我有用):

正在加载的iframe中的Javascript:

window.onload = function()
    {
        parent.document.getElementById('fileUploadIframe').style.height = document.body.clientHeight+5+'px';
        parent.document.getElementById('fileUploadIframe').style.width = document.body.clientWidth+18+'px';
    };

有必要在高度上添加4个或更多像素以删除滚动条(iframe的某些怪异错误/效果)。宽度甚至更奇怪,您可以安全地将18px添加到主体的宽度。另外,请确保已为iframe主体应用了CSS(如下)。

html, body {
   margin:0;
   padding:0;
   display:table;
}

iframe {
   border:0;
   padding:0;
   margin:0;
}

这是iframe的html:

<iframe id="fileUploadIframe" src="php/upload/singleUpload.html"></iframe>

这是我iframe中的所有代码:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>File Upload</title>
    <style type="text/css">
    html, body {
        margin:0;
        padding:0;
        display:table;
    }
    </style>
    <script type="text/javascript">
    window.onload = function()
    {
        parent.document.getElementById('fileUploadIframe').style.height = document.body.clientHeight+5+'px';
        parent.document.getElementById('fileUploadIframe').style.width = document.body.clientWidth+18+'px';
    };
    </script>
</head>
<body>
    This is a test.<br>
    testing
</body>
</html>

我已经在chrome中进行了测试,并在Firefox中进行了一些测试(在Windows XP中)。我还有更多测试要做,所以请告诉我这是如何工作的。


谢谢您,根据我的测试,这在移动浏览器中的运行效果惊人,这就是我调整iframe尺寸时遇到的问题!
Mircea Sandu

很高兴您喜欢它:-)我发现iframe在大多数情况下要比Ajax效率更高,并提供更好的浏览器支持。
www139 2015年

1
谢谢!!!主要是因为您是唯一指定WHERE放置代码而不假定人们知道的人。这个简单的解决方案非常适合我(Firefox,Chrome,Edge),可以在我的Wordpress网站的同一域中构建动态内容。我有一个窗体选择,它将输出各种长度的动态内容。iFrame调整精美。我确实需要调整.clientHeight + 5 +'px'; 和clientWidth + 18 +'px'; 要更多像素。而且我不确定为什么display:table; CSS中是必需的,因此出于我的目的将其注释掉。再次感谢。
Heres2u

1

这就是我的方法(在FF / Chrome中测试):

<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="page.html" width="100%" height="100" marginheight="0" frameborder="0" onload="autoResize(this);"></iframe>

如果Microsoft不在乎,谁应该在乎?
m3nda 2015年

1

以下是几种方法:

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;height:100%;width:100%" height="100%" width="100%"></iframe>
</body>

和另一种

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="100%" width="100%"></iframe>
</body>

如上所示隐藏2种替代方案的滚动

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;height:150%;width:150%" height="150%" width="150%"></iframe>
</body>

带有第二个代码的哈希

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:150%;width:150%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="150%" width="150%"></iframe>
</body>

为了隐藏iFrame的滚动条,父级被设置为“溢出:隐藏”以隐藏滚动条,并且iFrame的宽度和高度达到150%,这迫使滚动条超出页面,并且主体没有有滚动条的人可能不会想到iframe会超出页面的范围。这会隐藏全宽度的iFrame滚动条!

来源:设定iframe自动高度


您提供的示例应该使iframe完全内容完整,而不是自动调整iframe的高度以适合所有内部内容。它没有回答问题。
nickornotto


1

我发现此调整大小更好地工作:

function resizer(id)
{

    var doc = document.getElementById(id).contentWindow.document;
    var body_ = doc.body;
    var 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).height = height;
    document.getElementById(id).width = width;

}

请注意,样式对象已删除。


在Chrome / Win10上不适用于我-内容在底部被部分切除。
glenneroo

1

在jQuery中,这对我来说是最好的选择,对我有很大帮助!我等着你的帮助!

iframe

<iframe src="" frameborder="0" id="iframe" width="100%"></iframe>

jQuery的

<script>            
        var valueSize = $( "#iframe" ).offset();
        var totalsize = (valueSize.top * 2) + valueSize.left;

        $( "#iframe" ).height(totalsize);            

</script>

1

语境

我必须在网络扩展的背景下自己做。此网络扩展程序将一些UI注入到每个页面中,并且该UI位于内iframe。里面的内容iframe是动态的,因此我不得不重新调整iframe

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

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

在内部,iframe我更改了body样式以具有很大的尺寸。这将允许使用所有必要的空间来布置内部元素。制作widthheight100%都不适合我(我猜因为iframe具有默认值width = 300pxheight = 150px

/* something like this */
body {
  width: 99999px;
  height: 99999px;
}

然后,我将所有iframe UI注入了div并提供了一些样式

#ui-root {
  display: 'inline-block';     
}

在此应用程序中渲染我的应用程序后#ui-root(在React中,我在内部执行此操作componentDidMount),我像这样计算该div的尺寸并将其同步到父页面window.postMessage

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

在父框架中,我这样做:

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)

不错的解决方案!谢谢!
redelschaap


0

我知道这个职位很旧,但是我相信这是另一种方式。我只是在我的代码上实现。在页面加载和页面调整大小上均可完美运行:

var videoHeight;
var videoWidth;
var iframeHeight;
var iframeWidth;

function resizeIframe(){
    videoHeight = $('.video-container').height();//iframe parent div's height
    videoWidth = $('.video-container').width();//iframe parent div's width

    iframeHeight = $('.youtubeFrames').height(videoHeight);//iframe's height
    iframeWidth = $('.youtubeFrames').width(videoWidth);//iframe's width
}
resizeIframe();


$(window).on('resize', function(){
    resizeIframe();
});

0

放置在标头中的Javascript:

function resizeIframe(obj) {
        obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
      }

iframe html代码如下:

<iframe class="spec_iframe" seamless="seamless" frameborder="0" scrolling="no" id="iframe" onload="javascript:resizeIframe(this);" src="somepage.php" style="height: 1726px;"></iframe>

CSS样式表

>

.spec_iframe {
        width: 100%;
        overflow: hidden;
    }

0

对于angularjs指令属性:

G.directive ( 'previewIframe', function () {
return {
    restrict : 'A',
    replace : true,
    scope : true,
    link : function ( scope, elem, attrs ) {
        elem.on ( 'load', function ( e ) {
            var currentH = this.contentWindow.document.body.scrollHeight;
            this.style.height = eval( currentH ) + ( (25 / 100)* eval( currentH ) ) + 'px';
        } );
    }
};
} );

请注意,我插入了该百分比,以便您可以对通常针对iframe,文本,广告等所做的缩放进行计数,如果未实现任何缩放,则只需输入0


0

这是我在加载时或事情发生变化时的方式。

parent.jQuery("#frame").height(document.body.scrollHeight+50);

0

显然有很多情况,但是,我对文档和iframe具有相同的域,因此能够将其附加到iframe内容的末尾:

var parentContainer = parent.document.querySelector("iframe[src*=\"" + window.location.pathname + "\"]");
parentContainer.style.height = document.body.scrollHeight + 50 + 'px';

这将“查找”父容器,然后设置长度(加上50个像素的软键)以删除滚动条。

没有什么可以“观察”文档高度的变化,这对于我的用例来说是不需要的。在我的回答中,我确实提供了一种引用父容器的方法,而无需使用烘焙到父/ iframe内容中的ID。


0

如果您可以使用固定的宽高比,并且希望使用响应式iframe,那么此代码将对您有用。这只是CSS规则。

.iframe-container {
  overflow: hidden;
  /* Calculated from the aspect ration of the content (in case of 16:9 it is 9/16= 
  0.5625) */
  padding-top: 56.25%;
  position: relative;
}
.iframe-container iframe {
  border: 0;
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}

iframe必须将div作为容器。

<div class="iframe-container">
   <iframe src="http://example.org"></iframe>
</div>

源代码基于此站点,并且Ben Marshall拥有很好的解释。


-1

简单性:

var iframe = $("#myframe");
$(iframe.get(0).contentWindow).on("resize", function(){
    iframe.width(iframe.get(0).contentWindow.document.body.scrollWidth);
    iframe.height(iframe.get(0).contentWindow.document.body.scrollHeight);
});

-1

如果内容只是一个非常简单的html,最简单的方法是使用javascript删除iframe

HTML代码:

<div class="iframe">
    <iframe src="./mypage.html" frameborder="0" onload="removeIframe(this);"></iframe>
</div>

JavaScript代码:

function removeIframe(obj) {
    var iframeDocument = obj.contentDocument || obj.contentWindow.document;
    var mycontent = iframeDocument.getElementsByTagName("body")[0].innerHTML;
    obj.remove();
    document.getElementsByClassName("iframe")[0].innerHTML = mycontent;
}

1
这将更改父文档的大纲。如果您想将另一个文档作为带有figtitled的图形,则这不会使文档的轮廓保持简洁。不同的用例,但由于概述的原因,我想将代码段移至iframe。
亨利的猫,

-2
<iframe src="hello.html" sandbox="allow-same-origin"
        onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';this.style.width=(this.contentWindow.document.body.scrollWidth+20)+'px';">
</iframe>

这不是CSS,而是JS。
clifgriffin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.