【问题标题】:iFramed pages in IE9/10/11/Firefox do not update document.scrollHeight when the page changes in size?当页面大小发生变化时,IE9/10/11/Firefox 中的 iFramed 页面不会更新 document.scrollHeight?
【发布时间】:2014-05-28 06:14:45
【问题描述】:

我正在尝试使用 postMessage API 将我的页面高度从 iframe 发送到父页面。这个想法是,当 iframed 页面的总页面高度发生变化时,它将将该高度发送给父级。然后父级将调整 iframe 的高度以匹配。我目前在最新的 Google Chrome 中运行良好。

不幸的是,我在使用 IE9/10/11 和 Firefox 时遇到了问题。一旦 .scrollHeight 设置为最大,它就会保持在那里。尝试发送较小的高度只会发送之前的最高高度,即使原始页面的高度要小得多。

我认为这可能是因为页面所在的 iframe 影响了原始页面的高度。所以这实际上可能有一个CSS相关的解决方案?

这是我整理的一个简化的测试用例。此父页面包含一个 iframe,其中包含一个页面,该页面可以使用我添加的两个按钮来增加和减少其自身的高度。此外,第三个按钮获取页面高度并使用 postMessage API 将其发送给父级。

示例页面: http://iaviglobal.com/parent.html

我已将发送和接收的高度记录在控制台中。通过添加橙色块并发送文档高度来测试功能。然后隐藏橙色块并再次发送高度。在最新的 Chrome 中运行良好,在 IE 和 FF 中效果不佳。

任何帮助将不胜感激。

编辑:我已经确定如果我使用除<html><body> 之外的任何元素的高度,我可以避免这个问题。例如,报告<div id="main"> 的高度将给出一个准确的数字,而与浏览器无关。 <html><body> 似乎报告了 IE 和 Firefox 中的完整 iframe 高度,即使其中的内容没有填满那么多空间。

但是,如果我能得到准确的<html><body> 高度而不是使用<div>,那仍然是首选。

【问题讨论】:

    标签: javascript html css iframe


    【解决方案1】:

    有趣的是,这种行为可能是“正确”的行为。

    scrollHeight 属性必须返回运行这些的结果 步骤:

    1. 让视口高度为视口的高度,不包括滚动条的高度(如果有),或者为零(如果没有视口)。
    2. 如果该元素是根元素并且 Document 不是 quirks 模式返回 ma​​x(viewport 滚动区域高度, viewport 高度)
    3. 如果该元素是 HTML body 元素,则 Document 处于 quirks 模式并且该元素没有关联的滚动框,返回 max(视口滚动区域高度,视口高度)。
    4. 如果元素没有任何关联的 CSS 布局框,则返回零并终止这些步骤。 5.返回元素滚动区域的高度。

    参考:http://dev.w3.org/csswg/cssom-view/#dom-element-scrollheight

    根据this (somewhat old) comparisonbody.clientHeightbody.offsetHeight 似乎在标准模式下给出了你想要的值。

    【讨论】:

    • 感谢您的回复。我可以确认body.clientHeightbody.offsetHeight 在标准模式下都返回准确的数字。有趣的是,如果我引用 <body> 标记,我刚刚发现 .scrollHeight 在 IE/FF 中也有效。只是<html> 标签没有按您的预期工作。 .clientHeight.offsetHeight.scrollHeight 都只在 IE/FF 中的 <html> 标签上表现得很有趣。 Chrome 不在乎我是否使用<html> 标签来获取高度,它的工作原理与其他所有标签相同。
    【解决方案2】:

    我相信 IE/FF 会为您提供正确的行为,因为明确将元素高度设置为大于内容高度的值会使滚动高度等于该值 example

    您应该改用offsetHeight

    function postit() {
      parent.postMessage(document.getElementsByClassName("global-embed")[0].offsetHeight,"http://iaviglobal.com");
      console.log("iframe sent this height: " + document.getElementsByClassName("global-embed")[0].offsetHeight);
    };
    

    这是working copy of your example

    更新

    看起来在 IE9/10 中 html 元素继承了 iframe 高度,但使用 body 元素却可以按预期工作:

    //http://stackoverflow.com/a/17907562/328072
    function getInternetExplorerVersion()
    {
      var rv = -1;
      if (navigator.appName == 'Microsoft Internet Explorer')
      {
        var ua = navigator.userAgent;
        var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
          rv = parseFloat( RegExp.$1 );
      }
      else if (navigator.appName == 'Netscape')
      {
        var ua = navigator.userAgent;
        var re  = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
          rv = parseFloat( RegExp.$1 );
      }
      return rv;
    }
    function postit() {
      var elm = document.getElementsByClassName("global-embed")[0];
      var ie  = getInternetExplorerVersion();
      var h   = ie == -1 || ie >= 11 ? elm.offsetHeight : document.body.scrollHeight;     
      parent.postMessage(h,"http://iaviglobal.com");
      console.log("iframe sent this height: " + h);
    };
    

    更新了工作示例here

    【讨论】:

    • 在 Firefox 和 Chrome 中为我工作。但是IE9根本不起作用。尚未在 IE10 或 11 中测试过。
    • 感谢您的更新。我预计<html> 标签将继承自<iframe>。无论如何,这就是我最初观察到的。有什么方法可以直接看到 IE9/10 中的开发工具发生的情况?无论如何,感谢您为我提供了一种获取 <html> 高度的方法,然后默认为 IE9/10 的 <body>。我还没有在 IE11 中对此进行测试,但其他一切似乎都尽其所能。谢谢!
    • 我很高兴我能提供帮助,根据我的测试,IE11 使用 html 元素 offsetHeight 给出了正确的高度,这就是为什么我将它排除在使用 document.body.scrollHeight 之外.在开发工具中,选择 html 元素并检查计算的样式,但它在 IE11 中也会给出相同的结果。最好为htmlbody 元素创建一个脚本记录offset/scroll height,以查看浏览器的行为。
    【解决方案3】:

    我在 IE11 和 Firefox 29 中对此进行了测试。 当我将 class="global-embed" 从头元素移动到 iFrame 内的主体元素时,它可以完美运行!

    <html id="global-embed" lang="en">
    <body class="global-embed">
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多