【问题标题】:IE8 web font iframe bug workaroundsIE8 网络字体 iframe 错误解决方法
【发布时间】:2011-12-07 18:09:16
【问题描述】:

This blog post(那里的页面有点烦人)(顺便说一下,这不是我的博客)描述了我昨天在 Internet Explorer 8 中遇到的一个奇怪的错误。该错误涉及 .EOT 网络字体和<iframe> 元素。

我还没有广泛研究该错误的确切触发因素,但基本上是这样的情况,即使用网络字体的页面将内容加载到 <iframe> 使得框架使用网页字体被浏览器“污损”。使用 Web 字体呈现的之前正常的文本突然变成了看起来很糟糕的 Arial 或其他东西,有点像它自己。有时它会翻转回来,只是在随机用户交互(如鼠标移动)时再次降级。

那篇博文有一个例子。澄清一下,是包含页面搞砸了,而不是 <iframe> 中的页面(至少,到目前为止,我的经验是这样)。

有没有人找到比该博客中建议的更好的解决方法,即强制“重新加载” CSS <link> 元素,@font-face 声明来自何处? (我可以这样做,但会有点痛苦,而且它会迫使我将我的字体设置从我的文档中移出<head>,如果我记得这是一个性能问题;我将不得不四处寻找并找到再次花絮。)

编辑更新

好的here's a test page。这是主(容器)页面:

<!DOCTYPE html>
<html>
  <head>
    <style id='font_style'>
      @font-face {
        font-family: 'bold-display';
        src: url('DejaVuSans-Bold.eot');
      }
    </style>
    <style>
      .fancy { font-family: bold-display, "franklin gothic medium", "verdana", sans-serif; font-size: 32px; }
      iframe { width: 500px; height: 200px; }
      #floater {
        position: absolute;
        top: 100px; left: 100px;
        display: none;
      }
      #floater.showing {
        display: block;
      }
    </style>
    <script>
      function load() {
        var frame = document.createElement('iframe'),
          floater = document.getElementById('floater'),
          target = document.getElementById('target');

        frame.src = 'frame.html';
        target.appendChild(frame);
        floater.className += 'showing';
      }
      function unload() {
        var floater = document.getElementById('floater'),
          target = document.getElementById('target');
        target.innerHTML = '';
        floater.className = floater.className.replace(/\bshowing\b/g, '');
      }
    </script>
  </head>
  <body>
    <div class='fancy'>Hello World</div>
    <button type='button' onclick='load()'>Click Me</button>
    <div id='floater'>
      <div id='target'></div>
      <button type='button' onclick='unload()'>Close</button>
  </body>
</html>

框架页面具有相同的@font-face 和一个虚拟消息。

问题似乎与 使用 加载的字体和一个以上替代字体的列表有关。我(无缘无故)在我的“字体系列”值中加入了几个类似的更常见的字体。当我把它们放回:

 .title { font-family: bold-display, sans-serif; }

然后问题就消失了(或者至少到目前为止它似乎已经消失了)。

感谢那些提供帮助的人。对于@albert,添加一个总结你尝试过的答案,我会支持你:-)

【问题讨论】:

  • 你的代码在哪里?您使用的代码与该帖子完全相同吗?
  • 嗯,它是一个 iframe,它加载一个与父页面有相似 CSS 的页面,包括 @font-face 的东西。我可以尝试制作一个示例,但这很棘手,因为这个错误是一个错误。 (毫无疑问,这是一个浏览器错误;如果您看到它,那是完全显而易见的。)
  • 我无法复制它。 iframe 具有 xhtml 过渡文档类型,帖子具有 html5,帖子说您需要相同的文档类型...帖子样式文本是小屋,iframe 中的@font-face 引用 saxMonoRegular 等,等等,等等。帮助,只是根本看不到它
  • 好的,我看看能不能做个测试。应该不会太难。
  • 嗯……你说得对;看起来这比我想象的要多(而且可能比所描述的博客文章还要多)。我知道这个问题正在发生在我身上,即使你愿意,这种效果也是不可能做到的(它绘制了与“丢失”字体具有相同度量的虚假“替换”字体,这很奇怪),但也许我的页面还有其他问题导致了问题。

标签: css iframe internet-explorer-8 rendering font-face


【解决方案1】:

因此,以下内容不会影响性能(只要您的 CSS 大小合理),您可以将 &lt;link&gt; 标记保留在 &lt;head&gt; 中,并且它可以正常工作,但您基本上仍然在“重新加载”您的 &lt;link&gt; 元素(尽管您没有通过重置它们的 url 来这样做)。

在删除 &lt;iframe&gt; 元素时,只需执行以下操作:

var sheets = document.styleSheets;
for(var s = 0, slen = sheets.length; s < slen; s++) {
    sheets[s].disabled = true;
    sheets[s].disabled = false;
}

重新加载是我真正能想到的工作,因为它似乎正在从&lt;iframe&gt; 的垃圾收集中删除它。设置一个显然只适用于 IE 8 的 test page

注意:我最初无法使用 Google 网络字体重现此问题,因此必须专门下载 .eot 字体用于此问题。因此,您的工作可能首先使用 WOFF 字体,并且仅在必要时加载 EOT。

不确定这是否是您要查找的内容,但如果不是,请澄清一下,我会根据需要进行编辑。

更新 1:原因

所以,我已经缩小了问题的原因。如果发生以下情况,我只能重现(这是一个令人讨厌的人)。

  • &lt;iframe&gt; 包含在父元素中
  • 父元素的类已更改
  • 改变它所应用的元素的display(或者实际上,如果它不改变&lt;iframe&gt;元素的整体显示)

而且,据我所知,是的,它必须是类名。给定元素的id 上的相同步骤,我无法重现。严重地。这是一个讨厌的。我会继续挖掘。

更新 2:次要原因

如果绘制时&lt;iframe&gt; 未完全在浏览器窗口中,则它不会在&lt;iframe&gt; 窗口中加载字体,并且在必须重绘页面时卸载主窗口的字体(最明显的是调整大小时)。这是一个棘手的错误。

更新 3:应该有什么解决方案

不使用display: none;,而是将元素的高度和宽度设置为0pxoverflow: hidden;,你会得到和display none一样的效果,但是它不会从DOM,因此不会重绘页面并采用您的字体。我之前的test page 已经更新,所以你可以看到对以前的错误的影响。

【讨论】:

  • 天哪,我马上试试这个。
  • 这绝对似乎部分有效,但如果你注意到我对问题的编辑(基于@albert 促使我弄清楚的东西)问题比这更深.不过我会接受,因为你足够好,可以投入时间。
  • @Pointy 更新 1 已发布。找到了问题的原因。调查。此外,我对样式表进行扫描的修复目前似乎仍然有效,但我会看看是否找不到更好的解决方法。
  • @Pointy 我已经更新了应该是一个可行的解决方案。如果它不适合你,请告诉我。
  • 哦,我以为我已经拥有了(我第一次做赏金)。抱歉,我现在点击了。
【解决方案2】:

如果您只是通过 fontsquirrel.com 生成跨浏览器 @font-face 语法,我认为您甚至不会遇到问题。你想嵌入:

@font-face{
    font-family: 'DejaVuSansBook';
    src: url('DejaVuSans-webfont.eot'); /* ie9 compat mode */
    src: url('DejaVuSans-webfont.eot?#iefix') format('eot'),  /* ie 6-7-8 */
         url('DejaVuSans-webfont.woff') format('woff'), /* modern browsers */
         url('DejaVuSans-webfont.ttf') format('truetype'), /* Safari, Android, iOS */
         url('DejaVuSans-webfont.svg#webfontLXhJZR1n') format('svg'); /* Legacy iOS */
}

如果您发现语法错误,您也可以使用 webfont 加载器脚本。我没有将功能与上面回答的代码进行比较(我确信它有效),this is the js typekit 和 googlefonts 用于加载他们的字体。

【讨论】:

  • 不,这不是真的。事实上,我确实有这种 CSS。这个问题是一个 IE8 错误,毫无疑问。检查已在其他答案和 cmets 中链接的示例。
  • 好的。如果你有,事实上,有那个 CSS,你为什么不把它留在那里?我不明白你为什么要取消 .eot 的目标,即。我不是说你错了,但是 ie8 已经很老了....我原以为会有更多关于这样一个错误的文档。而且我从来没有遇到过使用这种语法的跨浏览器问题。只是想帮忙。
  • 我没有取出 .eot 的目标 IE。这个错误是真实的,但因为它只发生在 iframe 等这些有点不寻常的情况下,它实际上并没有影响那么多网站。换句话说,使用网络字体和来来去去的 iframe 相当少见。
  • 如果你有这样的css,但没有把它拿出来......我不知道你的意思。演示中的 css 在@font-face 语句中只有一个链接,指向 .eot 文件。
  • 是的,没错。问题原来是由对网络字体的reference 引起的。当 CSS 规则具有类似“font-family: the-webfont, Arial, Verdana, sans-serif;”的内容时- 根据我的经验,两个以上的字体系列名称 - 加载和卸载 iframe 时会触发该错误。阅读@Ktash 提供的广泛答案 - 这非常棒。当然,我非常感谢您的贡献。
【解决方案3】:

我在研究一个非常相似的情况时遇到了这个问答,只是没有涉及任何 iframe。所需要的只是使用谷歌网络字体和大量浮动 div 来导致 IE8 在重新加载后以不同方式呈现文本。看完这篇

问题似乎与使用加载的字体和多个替代字体的列表有关。

我将我的 css 中的字体堆栈更改为只有一个替代方案,并且错误消失了。

非常感谢您为我指明了正确的方向!

【讨论】:

    【解决方案4】:

    我最终使用的解决方案是

    @font-face {
        font-family: 'NewsGothicFSMedium';
        src: url('NewsGothic-Medium-webfont.eot');
        src: url('NewsGothic-Medium-webfont.eot?#iefix')  format('embedded-opentype'),
             url('NewsGothic-Medium-webfont.woff') format('woff'),
             url('NewsGothic-Medium-webfont.ttf') format('truetype'),
             url('NewsGothic-Medium-webfont.svg#webfont') format('svg');
        font-weight: normal;
        font-style: normal;
    }
    
    @font-face {
        font-family: 'NewsGothicFSMediumIframe';
        src: url('NewsGothic-Medium-webfont.eot');
        src: url('NewsGothic-Medium-webfont.eot?#iefix')  format('embedded-opentype'),
             url('NewsGothic-Medium-webfont.woff') format('woff'),
             url('NewsGothic-Medium-webfont.ttf') format('truetype'),
             url('NewsGothic-Medium-webfont.svg#webfont') format('svg');
        font-weight: normal;
        font-style: normal;
    }
    

    然后只需在 iframe css 中引用 iframe 字体系列。它有点额外的 css,但我认为如果你只使用一些字体,那么必须重新加载 css 更好。

    【讨论】:

    【解决方案5】:

    其他建议的解决方案都不适合我们,所以我们最终不得不简单地隐藏整个页面,直到页面加载。我们使用以下代码做到了这一点:

    <!--[if lte IE 8]>
        <style type="text/css">
            html {
                visibility: hidden;
            }
        </style>
        <script type="text/javascript">
            $(window).load(function() {
                $('html').css('visibility', 'visible');
            });
        </script>
    <![endif]-->
    

    【讨论】:

    • 这可能适用于某些页面布局,但初始页面加载后的动态更新可能会导致问题自发出现!
    【解决方案6】:

    IE

    根据https://github.com/stubbornella/csslint/wiki/Bulletproof-font-face,您可以通过简单地在第一个字体网址后添加一个问号并欺骗浏览器解释网址的方式来避免它。对我来说就像一个魅力。

    【讨论】:

    • 谢谢。在这种情况下,我认为这与它没有任何关系。在我的真实页面中,我使用的是 IE 的“保护”技术;在测试页面上,我只导入了IE的EOT字体。
    • 啊,好吧。我觉得我读你的帖子有点太快了,对不起。我在 Facebook 应用程序的 iframe 中遇到了奇怪的字体更改行为。在第一次访问页面时,它呈现正常,但在页面重新加载后,它会恢复为某些默认字体。很奇怪,它在 iframe 之外设置了正确的字体,因此 Facebook 焕然一新;)在 iframe 之外加载页面时,它可以在没有 ?#iefix 的情况下工作。
    【解决方案7】:

    我们遇到的问题似乎是当无法加载同名的 iframe(在我们的例子中是 404)时,IE 会(有时)卸载主页上的字体。我们的解决方案是重命名 iframed 页面上的字体(以防由于某些超出我们控制的原因无法加载字体)并确保正常加载。

    【讨论】:

      【解决方案8】:

      我的解决方案是为 IE8 设置一种排版的可能性。示例:

      general.css

      @font-face {
        font-family: 'patua-one'; /PatuaOneRegular';/
        src: url('../fonts/PatuaOne-Regular-webfont.eot');
        src: url('../fonts/PatuaOne-Regular-webfont.eot?#iefix') format('embedded-opentype'),
             url('../fonts/PatuaOne-Regular-webfont.woff') format('woff'),
             url('../fonts/PatuaOne-Regular-webfont.ttf') format('truetype'),
             url('../fonts/PatuaOne-Regular-webfont.svg#PatuaOneRegular') format('svg');
        font-weight: normal;
        font-style: normal;
      }
      
      body {
          font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
      }
      
      h1,h2,h3,h4,h5,h6 {
          font-family: patua-one,Arial,Helvetica Neue,Helvetica,sans-serif;
      }
      

      <!--[if IE 8]>
          <link rel="stylesheet" type="text/css" href="ie8.css">
      <![endif]-->
      

      ie8.css

      body {
          font-family: Arial;
      }
      
      h1,h2,h3,h4,h5,h6 {
          font-family: patua-one;
      }
      

      【讨论】:

      • 我重新格式化了您的 CSS 示例。请参阅How do I format my code blocks? 以获得更多帮助。 :-)
      • 是的,我同意 - 这似乎很重要。感谢您的回答!
      【解决方案9】:

      我遇到了类似的问题,但它是一个简单的框架集,而不是动态 iframe。根据ktash 的答案,这会将黑客集中到顶层框架中,而不会影响框架集周围可能加载的所有页面。

      条件块将覆盖仅 IE8 的 onload 处理程序。

      偶尔还有FOUC,但至少情况会自行纠正,而不是要求用户四处走动。

      <html>
      <head>
      <script>
      function markFrameLoaded() { 
          // noop for the well behaved browsers of the world
      }
      </script>
      <!--[if IE 8]>
      <script>
      function markFrameLoaded() {
          var frameCount = window.frames.length;
          for ( var f = 0 ; f < frameCount ; f++ ) {
              var styleCount = window.frames[f].document.styleSheets.length;
              for ( var s = 0 ; s < styleCount ; s++ ) {
                  var sheet = window.frames[f].document.styleSheets[s];
                  sheet.disabled = true;
                  sheet.disabled = false;
              }
          }
      }
      </script> 
      <![endif]-->
      </head>
      <frameset rows="*,*">
      <frame src="top.html" onload="markFrameLoaded()">
      <frame src="bottom.html" onload="markFrameLoaded()">
      </frameset>
      </html>
      

      【讨论】:

        猜你喜欢
        • 2014-03-21
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-25
        • 1970-01-01
        • 2010-10-01
        相关资源
        最近更新 更多