IE8 网页字体 iframe 错误解决方法

发布于 2024-12-10 05:01:16 字数 2690 浏览 0 评论 0 原文

这篇博文(那里的页面有点烦人)(顺便说一句,这不是我的博客)描述了我昨天仅在 Internet Explorer 8 中遇到的一个奇怪的错误。该错误涉及 .EOT Web 字体和

我还没有广泛研究该错误的确切触发因素,但基本上情况是,使用网络字体的页面将内容加载到

该博客文章有一个例子。需要澄清的是,混乱的是包含页面,而不是

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

编辑 - 更新

确定这是一个测试页。这是主(容器)页面:

<!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,添加一个总结你尝试过的答案,我会投票给你:-)

This blog post (slightly annoying page there) (and that's not my blog by the way) describes a bizarre bug I ran into yesterday in Internet Explorer 8 only. The bug involves .EOT web fonts and <iframe> elements.

I haven't extensively researched the exact trigger for the bug, but it's basically the case that a page using a web font that loads content into an <iframe> such that the frame also uses a web font becomes "defaced" by the browser. The previously-OK text rendered with the web font suddenly shifts to awful-looking Arial or something else, sort-of on its own. Sometimes it flips back, only to degrade again on random user interactions like mouse moves.

That blog post has an example. To clarify, it's the containing page that gets messed up, not the page in the <iframe> (at least, that's the case so far in my experience).

Has anybody found a better workaround than what's suggested in that blog, which is to force a "reload" of the CSS <link> element from whence the @font-face declarations come? (I could do that but it'd be a minor pain, plus it would force me to move my font setup out of my document <head> which if I recall is a performance issue; I'll have to scrounge around and find that tidbit again.)

editupdate

OK here's a test page. Here's the main (container) 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>

The frame page has the same @font-face and a dummy message.

The problem appears to have something to do with using the loaded fonts with a list of more than one alternate font. I (for no good reason) had tossed in a couple of similar more-common fonts in my "font-family" values. When I dropped them back to:

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

then the problem went away (or at least it seems to have gone away so far).

Thanks to those who've helped out. To @albert, add an answer summarizing what you tried and I'll upvote you :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

违心° 2024-12-17 05:01:16

因此,以下内容不会影响性能(只要 CSS 大小合理),您可以将 标记保留在 < 中;head>,并且它的工作没有问题,但您基本上仍然是在“重新加载”您的 元素(尽管您不是通过重置其 url 来做到这一点)。

在删除

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

重新加载是我真正能想到的工作,因为它似乎在垃圾收集中从 <; 中删除它。 iframe>。设置一个显然仅适用于 IE 8 的测试页面

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

不太确定这是否是您正在寻找的内容,但如果不是,请澄清,我将根据需要进行编辑。

更新 1:原因

因此,我已经缩小了问题原因的范围。我只有在发生以下情况时才能重现(这是一个令人讨厌的人)。

  • 并且
  • 父元素的类已更改
  • 该类不会更改其所在元素的显示被应用于(或者实际上,如果它不改变

并且,据我所知,是的,它必须是类名称。我无法在元素的 id 上执行相同的步骤来重现。严重地。这是一个令人讨厌的。我会继续挖掘一点。

更新 2:次要原因

如果

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

不要使用 display: none;,而是将元素的高度和宽度设置为 0pxoverflow:hidden;,您将获得与 display none 相同的效果,但它不会将其从 DOM 中删除,从而不会重新绘制页面并获取您的字体。我之前的测试页面已更新,因此您可以看到对以前的错误的影响。

So, there is no performance hit with the following (as long as your CSS is reasonably sized), you get to leave the <link> tag in <head>, and it works without issue, but you are still basically 'reloading' your <link> elements (though you are not doing so by resetting their url).

On the removal of the <iframe> element, simply do the following:

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

Reloading is all I can really think of as working since it seems to be removing it in garbage collection from the <iframe>. Set up a test page that obviously only works for IE 8.

Of Note: I was originally unable to reprodcue this issue using Google web fonts, and had to specifically download a .eot font for use for this. So your work around maybe to use WOFF fonts first, and only load EOT if necessary.

Not exactly sure if this is what you were looking for, but if it's not, please clarify and I'll edit as necessary.

Update 1: The cause

So, I've narrowed down the cause of the issue. I am only able to reproduce if the following occurs (and this is a nasty one folks).

  • And <iframe> is contained within a parent element
  • The parent element's class is changed
  • The class does not change the display of the element it is being applied to (or really, if it does not change the overall display on the <iframe> element)

And, from what I can tell, yes, it has to be the class name. I was unable to reproduce given the same steps on the id of an element. Seriously. This one is a nasty one. I'll keep digging a bit.

Update 2: A Secondary Cause

If the <iframe> is not fully in the browser window on draw, it will not load the font within the <iframe> window, and will unload the font for the main window whenever it has to redraw the page (most notably when it is resized). This is a gnarly bug.

Update 3: What should be a solution

Instead of using display: none;, set the height and the width of the element to be 0px and the overflow: hidden;, and you'll get the same effect as display none, but it will not remove it from the DOM, thereby not redrawing the page and taking your font. My test page from before has been updated, so you can see the effect on what used to be the bug.

一腔孤↑勇 2024-12-17 05:01:16

如果您刚刚通过 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 加载脚本。我没有将功能与上面回答的代码进行比较(我确信它有效),这是 js typekit 和 googlefonts 用于加载字体的。

If you just generated cross-browser @font-face syntax via fontsquirrel.com, I don't think you'd even have an issue. you want to be embedding:

@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 */
}

you could also use the webfont loader script if you find the syntax failing. I didn't compare functionality to the code answered above (I'm sure it works), this is the js typekit and googlefonts use to load their fonts.

猥琐帝 2024-12-17 05:01:16

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

该问题似乎与将加载的字体与多个备用字体的列表一起使用有关。

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

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

I came across this q&a while researching a very similar situation with the exception of no iframe whatsoever being involved. All it took was using a google web font and a lot of floated divs to cause IE8 to render the text differently after reload. Having read this

The problem appears to have something to do with using the loaded fonts with a list of more than one alternate font.

I changed the font-stack in my css to only a single alternative, and the bug went away.

Thanks a lot for pointing me in the right direction!

爱的十字路口 2024-12-17 05:01:16

我最终使用的解决方案是

@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 更好。

The solution I ended up using was

@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;
}

Then just reference the Iframe font-family within the iframe css. Its a little extra css but I think its better then having to reload css if you are only using a few fonts.

秋心╮凉 2024-12-17 05:01:16

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

<!--[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]-->

None of the other suggested solutions worked for us, so we ended up having to simply keep the entire page hidden until the page was loaded. We did that with the following piece of code:

<!--[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]-->
岁月蹉跎了容颜 2024-12-17 05:01:16

IE < 9 在处理字体 src 属性的方式上有一个错误。

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

IE < 9 has a bug in the way it handles the src attribute of the font.

According to https://github.com/stubbornella/csslint/wiki/Bulletproof-font-face , you can avoid it by simply adding a questionmark after the first font url and trick the way the browser interprets the url. Worked like a charm for me.

无人问我粥可暖 2024-12-17 05:01:16

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

The problem we encountered seemed to be that when an iframe with the same name was unable to be loaded (a 404 in our case), IE would (sometimes) unload the font on the main page. Our solution was to rename the font on the iframed page (in case the font can't be loaded for some reason beyond our control) and ensure that it is properly loaded normally.

意犹 2024-12-17 05:01:16

我的解决方案是只为 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;
}

My solution has been to set just one possibility of typography for IE8. Example:

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;
}
长发绾君心 2024-12-17 05:01:16

我有一个类似的问题,但它是一个简单的框架集,而不是动态 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>

I had a similar problem, but it was with a simple frameset, not with dynamic iframes. Riffing on the answer from ktash, this centralizes the hack into the top level frame, without impacting all the pages that might load around the frameset.

The conditional block will override the onload handler for just IE8.

There is still a FOUC occasionally, but at least the situation corrects itself rather than requiring the user to move around.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文