jQuery在加载时获取iframe内容的高度


84

我在Main.php的iframe中加载了一个帮助页面help.php,将页面加载到iframe中后,如何获取该页面的高度?

我问这个问题是因为我无法将iframe的高度设置为100%或自动。这就是为什么我认为我需要使用javascript ..我正在使用jQuery

CSS:

body {
    margin: 0;
    padding: 0;
}
.container {
    width: 900px;
    height: 100%;
    margin: 0 auto;
    background: silver;
}
.help-div {
    display: none;
    width: 850px;
    height: 100%;
    position: absolute;
    top: 100px;
    background: orange;
}
#help-frame {
    width: 100%;
    height: auto;
    margin:0;
    padding:0;
}

JS:

$(document).ready(function () {
    $("a.open-help").click(function () {
        $(".help-div").show();
        return false;
    })
})

HTML:

<div class='container'>
    <!-- -->
    <div class='help-div'>
        <p>This is a div with an iframe loading the help page</p>
        <iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
    </div>  <a class="open-help" href="#">open Help in iFrame</a>

    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
</div>

iFrame的内容是否与其所在页面来自同一域?
安德鲁(Andrew)2010年

是的,这是安德鲁,我想使用iFrame,因为我在帮助页面中使用了定位
标记

Answers:


102

好的,我终于找到了一个好的解决方案:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

由于某些浏览器(较早的Safari和Opera)报告的加载在CSS渲染之前完成,因此您需要设置一个微型超时并清空并重新分配iframe的src。

$('iframe').load(function() {
    setTimeout(iResize, 50);
    // Safari and Opera need a kick-start.
    var iSource = document.getElementById('your-iframe-id').src;
    document.getElementById('your-iframe-id').src = '';
    document.getElementById('your-iframe-id').src = iSource;
});
function iResize() {
    document.getElementById('your-iframe-id').style.height = 
    document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px';
}

此解决方案效果很好,因为上面的内容只是从容器内iframe一致的大小中获取了大小,而这只是real大小
rickyduck 2011年

2
我相信load事件会在同一事件循环上触发,因此setTimout为1毫秒也可以正常工作
George Mauer

hhmmm任何人都知道如何获取在加载父级时隐藏的iframe的高度。这个方法带回0
JT ......

1
您可能需要document高度,而不是body高度。使用jQuery可以使用$(this.contentWindow.document).height()
vpiTriumph

对于较旧的版本,即iframe.contentDocument.body.offsetHeight将起作用。stackoverflow.com/questions/2684693/...
user1087079

50

较为简单的答案是.contents()用于获取iframe。但是,有趣的是,我相信由于身体的填充,它返回的值与我在原始答案中使用代码得到的值不同。

$('iframe').contents().height() + 'is the height'

这是我为跨域通信所做的工作,因此恐怕它可能不必要地复杂。首先,我将jQuery放在iFrame的文档中;这样会消耗更多的内存,但是不会增加加载时间,因为脚本只需要加载一次。

使用iFrame的jQuery尽可能早地测量iframe主体的高度(onDOMReady),然后将URL哈希设置为该高度。在父文档中,将onload事件添加到iFrame标记中,该事件将查看iframe的位置并提取所需的值。因为onDOMReady总是会在文档的load事件之前发生,所以可以肯定的是,该值将得到正确的通信,而不会出现使条件复杂化的情况。

换一种说法:

...在Help.php中:

var getDocumentHeight = function() {
    if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady
        location.hash = $('body').height(); 
        // at this point the document address will be something like help.php#1552
    }
};
$(getDocumentHeight);

...并在父文档中:

var getIFrameHeight = function() {
    var iFrame = $('iframe')[0]; // this will return the DOM element
    var strHash = iFrame.contentDocument.location.hash;
    alert(strHash); // will return something like '#1552'
};
$('iframe').bind('load', getIFrameHeight );

您好安德鲁到目前为止非常好的帮助。contents()效果很好,但是我仍然需要使用带宽调节器对其进行测试。也许您可以使用innerHeight()属性。我在FF(OSX)中使用您的解决方案将高度放在哈希表中时遇到问题。FF似乎继续在无限循环中加载getDocumentHeight()函数?Safari是很好..
FFish

有趣。我添加了一项检查,以防止在已有值的情况下设置哈希值。您可能需要调整这个,如果你是一个哈希值加载Help.php(例如<iframe src="../Help.php#introduction" />
安德鲁

顺便说一句,假设您可以针对高度差异进行调整,则可能不需要使用散列来与iframe进行通信。如果您确实使用了哈希方法,则sleep(5)在您的Help.php中放置a也应该是测试任何竞争条件的好方法。如果iframe确实以某种方式触发onLoadonDOMReady,则应在此处显示。
安德鲁(Andrew)2010年

23

我发现以下内容可在Chrome,Firefox和IE11上运行:

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

Iframe内容完成加载后,事件将触发,并将IFrames的高度设置为其内容的高度。这仅适用于与IFrame属于同一域的页面。


工作正常,但对于宽度我必须这样做,否则内容将被剪切$('iframe')。width($('iframe')。contents()。width()+ 30);
Geomorillo 2014年

@AminGhaderi在Firefox 40.0.3中对我工作正常
mixkat 2015年

@mixkat我确实通过此解决方案和本主题中的所有解决方案在iframe中加载了网站,但对我来说却行不通!我认为这种解决方案只对一页有效,而当我们将完整的网站加载到iframe中时,这种解决方案不起作用。我的英语很不好,希望你能理解。
Amin Ghaderi'9

@AminGhaderi,如果我没错,您希望此方法适用于您站点中的每个页面,但是当然,它不适用于所有页面,因为它在加载框架时仅运行一次。因此它可以在第一页上正常工作,但是如果您希望它在更长的页面上工作,则必须通过重新加载新页面的框架或在其中的其他位置调用content.height来再次执行此操作。您的流程
mixkat 2015年

9

如今,没有jQuery的代码很简单:

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

取消挂起事件:

frame.removeEventListener('load', syncHeight)

3
漂亮又简单!不幸的是,不适用于跨域iframe :(
TimoSolo

3
是的,运气不错。我会利用iframe-resizer库来实现。当然,您需要同时控制两个域才能起作用。
cchamberlain

6

您不需要在iframe中使用jquery来执行此操作,但是我使用它是因为代码非常简单...

将其放入iframe中的文档中。

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

在上面添加了五个以消除小窗口上的滚动条,它的尺寸从来都不是完美的。

而这在您的父文档中。

function set_size(ht)
{
$("#iframeId").css('height',ht);
}

如果要在iframe中显示PDF,这也将不起作用。
杰森·福利亚

抱歉,您的示例“内部框架”显然基于jQuery。
T-moty

4

这是对我有用的正确答案

$(document).ready(function () {
        function resizeIframe() {
            if ($('iframe').contents().find('html').height() > 100) {
                $('iframe').height(($('iframe').contents().find('html').height()) + 'px')
            } else {
                setTimeout(function (e) {
                    resizeIframe();
                }, 50);
            }
        }
        resizeIframe();
    });

4

简单的单线从默认的最小高度开始,然后增加到内容大小。

<iframe src="http://url.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>



1

这是一个jQuery免费解决方案,可以在iframe中与SPA一起使用

document.getElementById('iframe-id').addEventListener('load', function () {
  let that = this;
  setTimeout(function () {
    that.style.height = that.contentWindow.document.body.offsetHeight + 'px';
  }, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate
});

1

这是我对ES6友好的非jQuery技巧

document.querySelector('iframe').addEventListener('load', function() {
    const iframeBody = this.contentWindow.document.body;
    const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight);
    this.style.height = `${height}px`;
});
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.