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

Posted

技术标签:

【中文标题】jquery在加载时获取iframe内容的高度【英文标题】:jquery get height of iframe content when loaded 【发布时间】:2011-04-20 06:08:01 【问题描述】:

我有一个帮助页面 help.php,我在 main.php 的 iframe 中加载它 在 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"   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 的内容是否来自与其所在页面相同的域? 是的,是安德鲁,我想使用 iFrame,因为我在帮助页面中使用了锚点 【参考方案1】:

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

$('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 大小 我相信加载事件会在同一个事件循环上触发,因此 1 毫秒的 setTimout 也可以正常工作 hhmmm 任何人都知道如何获取在加载父级时隐藏的 iframe 的高度。此方法带回 0。 您可能需要document 高度,而不是body 高度。使用 jQuery,您可以使用 $(this.contentWindow.document).height() 获取它。 对于较旧的即 iframe.contentDocument.body.offsetHeight 将起作用。 ***.com/questions/2684693/…【参考方案2】:

不太复杂的答案是使用.contents() 获取iframe。有趣的是,我相信,由于主体上的填充,它返回的值与我在原始答案中使用代码得到的值不同。

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

这就是我为跨域通信所做的,所以我担心它可能会不必要地复杂。首先,我将 jQuery 放入 iFrame 的文档中;这会消耗更多的内存,但它不应该增加加载时间,因为脚本只需要加载一次。

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

换句话说:

...在 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很好.. 有趣。如果那里已经存在值,我添加了一个检查,以防止设置散列。如果您使用哈希值(例如 &lt;iframe src="../Help.php#introduction" /&gt;)加载 Help.php,您可能需要对此进行调整 顺便说一句,假设您可以调整高度的差异,您可能不需要使用哈希值在 iframe 之外进行通信。如果您确实使用了哈希方法,那么在您的 Help.php 中添加 sleep(5) 也应该是测试任何竞争条件的好方法。如果 iframe 在 onDOMReady 之前以某种方式触发 onLoad,它应该会显示在这里。【参考方案3】:

我发现以下内容适用于 Chrome、Firefox 和 IE11:

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

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

【讨论】:

工作正常,但对于宽度我必须这样做,否则内容会被剪切 $('iframe').width($('iframe').contents().width()+ 30); @AminGhaderi 在 Firefox 40.0.3 中工作正常 @mixkat 我确实通过此解决方案和本主题中的所有解决方案在 iframe 中加载了一个网站,但对我来说不起作用!我认为这个解决方案确实适用于一个页面,并且当我们将完整的网站加载到 iframe 中时不起作用。我的英语很差,希望你能理解。 @AminGhaderi 如果我做对了,您希望这适用于您网站中的每个页面,但当然这不适用于所有页面,因为它仅在您加载框架时运行一次。所以它适用于第一页,但是如果你希望它适用于更长的页面,你将不得不再次通过新页面加载框架或在其他某个点调用 contents.height你的流量【参考方案4】:

在没有 jQuery 的情况下执行此操作的代码现在很简单:

const frame = document.querySelector('iframe')
function syncHeight() 
  this.style.height = `$this.contentWindow.document.body.offsetHeightpx`

frame.addEventListener('load', syncHeight)

取消挂钩事件:

frame.removeEventListener('load', syncHeight)

【讨论】:

又好又简单!不幸的是,它不适用于跨域 iframe :( 是的,运气不好。我会为此利用 iframe-resizer 库。当然,您需要同时控制这两个域才能正常工作。【参考方案5】:

您不需要 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 的。【参考方案6】:

这是对我有用的正确答案

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

【讨论】:

【参考方案7】:

简单的单行 以默认的最小高度开始并增加内容大小。

&lt;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;"&gt;&lt;/iframe&gt;

【讨论】:

【参考方案8】:

已接受答案的 $('iframe').load 现在将产生 a.indexOf is not a function 错误。可以更新为:

$('iframe').on('load', function() 
  // ...
);

自 jQuery 1.8 起已弃用与 .load 类似的其他几个:"Uncaught TypeError: a.indexOf is not a function" error when opening new foundation project

【讨论】:

【参考方案9】:

这是我对 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 = `$heightpx`;
);

【讨论】:

【参考方案10】:

这是一个免费的 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
);

【讨论】:

【参考方案11】:

这是我的解决方案,使用纯 JS 来查找 iframe 内容的总高度。 注意:

    加载 iframe 后调用此函数。

    iframe 内容必须与主机页面位于同一域中。

     function getIframeBodyTotalHeight() 
     var frm = document.getElementById("appframe");
     var frm_body = frm.contentWindow.document.body;
    
     var body_height = parseInt(frm_body.offsetHeight);
     var body_margin_top = parseInt(window.getComputedStyle(frm_body).getPropertyValue('margin-top').replace("px",""));
     var body_margin_bottom = parseInt(window.getComputedStyle(frm_body).getPropertyValue('margin-bottom').replace("px",""));
     var body_padding_top = parseInt(window.getComputedStyle(frm_body).getPropertyValue('padding-top').replace("px", ""));
     var body_padding_bottom = parseInt(window.getComputedStyle(frm_body).getPropertyValue('padding-bottom').replace("px", ""));
    
     var result = body_height + body_margin_top + body_margin_bottom + body_padding_top + body_padding_bottom;
     return result;
    
    

【讨论】:

以上是关于jquery在加载时获取iframe内容的高度的主要内容,如果未能解决你的问题,请参考以下文章

使用jQuery动态调整iframe高度,以及jQuery对dom元素的监听

jq 在iframe中点击按钮,父元素触发事件

jQuery解决iframe高度自适应代码

如何让iframe自适应高度

iframe 高度随引用的页面内容自动变化

根据内容动态调整 iframe 高度