This blog post(那里有点讨厌的页面)(顺便说一下,这不是我的博客)描述了我昨天在Internet Explorer 8中遇到的一个奇怪的错误。该错误涉及.EOT网络字体和<iframe>
元素。
我没有广泛研究错误的确切触发器,但基本上情况是使用网页字体的网页将内容加载到<iframe>
,以便框架也使用网络字体被浏览器变为“污损”。使用Web字体呈现的先前正常文本突然转变为看起来很糟糕的Arial或其他类似的东西。有时它会翻转,只会在鼠标移动等随机用户交互中再次降级。
该博客文章有一个例子。澄清一下,它是包含在内的页面,而不是<iframe>
中的页面(至少,就我的经验而言,情况就是如此)。
是否有人找到了比该博客中建议的更好的解决方法,即强制从<link>
声明的来源“重新加载”CSS @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
和虚拟消息。
这个问题似乎与使用加载的字体有关,其中包含多个备用字体的列表。我(没有充分理由)在我的“font-family”值中抛出了几个类似的更常见的字体。当我把它们放回去时:
.title { font-family: bold-display, sans-serif; }
然后问题消失了(或者至少它似乎已经消失了。)
感谢那些帮助过的人。致@albert,添加一个总结你尝试过的答案的答案,我会向你投票: - )
答案 0 :(得分:25)
因此,以下内容没有性能影响(只要CSS的大小合理),您可以将<link>
标记保留在<head>
中,它没有问题,但你仍然基本上“重新加载”你的<link>
元素(虽然你没有通过重置他们的网址这样做)。
删除<iframe>
元素后,只需执行以下操作:
var sheets = document.styleSheets;
for(var s = 0, slen = sheets.length; s < slen; s++) {
sheets[s].disabled = true;
sheets[s].disabled = false;
}
重新加载是我真正想到的所有工作,因为它似乎是从<iframe>
中的垃圾收集中删除它。设置test page,显然只适用于IE 8。
注意:我原本无法使用Google网络字体重新解决此问题,并且必须专门下载.eot
字体才能使用此字体。所以你的工作可能首先使用WOFF字体,并且只在必要时加载EOT。
不确定这是否是您所寻找的,但如果不是,请澄清,我会根据需要进行编辑。
更新1:原因
所以,我已经缩小了问题的原因。如果发生以下情况,我只能复制(这是一个令人讨厌的人)。
<iframe>
包含在父元素display
(或者实际上,如果它不会更改<iframe>
元素上的整体显示) 而且,据我所知,是的,它必须是班级名称。在元素的id
上给出相同的步骤,我无法重现。认真。这个是令人讨厌的。我会继续挖掘一下。
更新2:次要原因
如果<iframe>
在浏览器窗口中没有完全显示,它将不会在<iframe>
窗口中加载字体,并且只要必须重新绘制主窗口,就会卸载主窗口的字体页面(最值得注意的是调整大小时)。这是一个粗糙的错误。
更新3:应该是什么解决方案
而不是使用display: none;
,将元素的高度和宽度设置为0px
和overflow: hidden;
,您将获得与显示无效相同的效果,但它不会将其从DOM中删除,因此不会重新绘制页面并使用您的字体。我之前的test page已经更新,因此您可以看到对以前的错误的影响。
答案 1 :(得分: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 loader脚本。我没有将功能与上面回答的代码进行比较(我确信它有效),this is the js typekit和googlefonts用于加载他们的字体。
答案 2 :(得分:2)
我偶然发现了这个q&amp; a研究一个非常相似的情况,除了没有任何参与的iframe。所有这一切都是使用谷歌网络字体和许多浮动的divs导致IE8重新加载后以不同的方式呈现文本。读过这个
问题似乎与使用带有多个备用字体列表的已加载字体有关。
我将我的css中的font-stack更改为只有一个替代方案,并且bug消失了。
非常感谢你指出我正确的方向!
答案 3 :(得分:2)
我最终使用的解决方案是
@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更好。
答案 4 :(得分:1)
其他建议的解决方案都没有为我们工作,所以我们最终只需要隐藏整个页面,直到页面加载完毕。我们用以下代码完成了这个:
<!--[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]-->
答案 5 :(得分:1)
IE&lt; 9处理字体的src属性的方式有一个错误。
根据https://github.com/stubbornella/csslint/wiki/Bulletproof-font-face,你可以通过简单地在第一个字体网址后面添加一个问号来避免它,并欺骗浏览器解释网址的方式。对我来说就像一个魅力。
答案 6 :(得分:1)
我们遇到的问题似乎是当无法加载具有相同名称的iframe时(在我们的例子中是404),IE会(有时)卸载主页面上的字体。我们的解决方案是重命名iframed页面上的字体(如果由于某种原因无法加载字体而无法加载)并确保正常加载它。
答案 7 :(得分:1)
我的解决方案是为IE8设置排版的一种可能性。例如:
@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]-->
body {
font-family: Arial;
}
h1,h2,h3,h4,h5,h6 {
font-family: patua-one;
}
答案 8 :(得分:1)
我遇到了类似的问题,但它是一个简单的框架集,而不是动态的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>