在 iframe 中页面具有不同的高度

page has different height when inside an iframe

我用谷歌搜索了一下,找到了一些线索,但我无法找到任何有用的线索:

我有一个带有 iframe 的页面,其 src 指向外部页面(跨域)。当 child/iframed 页面加载时,它会发布一条关于其高度的消息。我在javascript中放了一个console.log的高度。如果我在单独的 window 中打开该页面(换句话说,在单独的选项卡中键入 iframe 的 src URL),控制台会记录预期的高度。

但是,当我使用 iframe 打开父页面时,控制台记录 0 或非常不正确的值 150。我查看了 css 和 html,并且我没有 150 的任何规格。任何人都知道这是怎么回事吗?

抽象代码:

父级 HTML:

...
<iframe src="example.childpage.com" scrolling="no" frameBorder="0"></iframe>
...

父级 Javascript:

...
$(document).ready(function(){
    window.addEventListener('message', function(m){
        var messageData = m.data;
        if(messageData.type=='document-loaded' && 
            messageData.hasOwnProperty('height'){
            resize_iframe(messageData.height); //function defined else where 
                                               //and works
        };
});
...

IFrame Javascript:

...
$(document).ready(function(){
    var body = document.body;
    var html = document.documentElement;
    var maxHeight = Math.max(body.scrollHeight, body.offsetHeight, 
        html.clientHeight, html.scrollHeight, html.offsetHeight);
    //Logs height correctly when opened in a separate window but not when 
    //iframed
    console.log("POSTING HEIGHT", maxHeight); 
    window.parent.postMessage({'type':'document-loaded', 'height': maxHeight}, 
        PARENT_HOST_URL); //PARENT_HOST_URL defined elsewhere
});
...

我知道我这里混合了 jquery 和原版 javascript;我已经完成了上面显示的 $(document).height() 和 Math.max() 以获得高度,但是这两种方式仍然存在相同的问题。

非常感谢!

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

$('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';
}

我有一个循环遍历尚未访问的元素并调用 $(element).hide() 的函数——它设置样式显示:none.

事实证明,计算元素的高度是根据其在实际页面上的可见性而定的,而不管它是否在 iframe 中。所以浏览器看不到它,所以高度计算错误(仍然很奇怪它返回一个随机的 150px 值)。这就解释了为什么它在单独的页面上计算正确。

我只是将可见性设置为隐藏,而不是执行 hide(),这解决了我获得不正确高度的问题。