老爷车IE8如何兼容图标字体
前言
首先这个标题再详细的说就是如何解决font-face在IE8下间歇性出现图标字体渲染失败的解决方案。
如果你还不知道什么是图标字体,可以先阅读:链接1,链接2,链接3
先看在IE8下的问题:

而正常的应该是这样:

可以看到所以图标都显示不了,最关键的是还显示出他本身的字符,这绝对是不能忍的,必须解决。
问题的原因到底是什么?
这个页面是为了快速一览图标字体的页面,这两个截图都是在IE8下截图的,所以可以看到font-face不是不兼容IE8,而是间歇性的撂挑子(出问题),至于问题原因:
我猜测:是因为字体并不阻塞页面显示,当第一次打开页面,字体文件没有缓存,且字体在页面打开后才载入进来,导致浏览器没有重新渲染页面中使用图标字体的字符,才导致此问题出现的
1、搭建测试环境
首先要100%复现问题,确定bug原因。我是win8的开发机,用Oracle VM VirtualBox建立虚拟机,IE6 8 9各一台,现在用IE8测试

开发环境是Visual Studio 2013,把项目跑起来后,开启Fiddler做虚拟机的代理服务器,也就是将Fiddler作为我的真实机的反向代理服务器,这样可以让虚拟机连接我的真实机的localhost地址,来达到远程VS调试的功能。
当然你可以直接把web文件发布到局域网内网IP,然后虚拟机访问,在本例中是可以的,但是那样VS是无法使用调试(debug)功能的。

如上图所示虚拟机成功连接真实的localhost,但目前是没问题的,我们需要利用Fiddler来模拟网络问题。
2、用Fiddler模拟网络问题
猜测是字体返回过慢,所以可以利用Fiddler的 BreakPoints ,即断点功能。
使用Fiddler-【Rules】-【Automatic Breakpoints】-【After Response】断点功能。

启用【After Response】即响应后断点,即响应已经发送至服务器,服务器也将资源返回给Fiddler,此时Fiddler等待其他资源都响应完成后,再返回给浏览器,以人为制造上述猜想的发生场景,过程如下图:

顺便一提,在本例中使用【Before Request】也是可以的,因为对于浏览器而言,使用请求前断点和响应后断点都是一样的。
接下来在虚拟机中的IE8按Ctrl+F5,强制所有资源均从新加载,在Fiddler中,把所有非字体资源文件都【Run to Completion】通过,转发给浏览器,最后再将字体转发给浏览器。

3、稳定复现
可以看到,问题又复现了:

如果此时关闭断点,再在虚拟机中清空缓存,并按Ctrl+F5 多少次,也无法复现此问题,只要使用Fiddler断点,就可以100%复现此问题。
问题找到了,就是后加载进来无法渲染,想办法强制触发渲染就可以了。
如何解决此问题?
解决方案1:加载完成后调整下浏览器大小
大家应该都知道,调整浏览器大小会造成网页重绘与回流,会让页面几乎所有元素重新绘制。因为重新绘制样式了,所以自然也就可以了解决图标字体渲染失败的问题。
缺点自然不用说,这等于没解决,不过我们可以利用重绘后图标生效的特性来让强制令其页面回流重绘。
解决方案2:强制回流
既然我们要让所有图标字体都生效,那么最好的办法是让页面发生大面积回流,以触发整页重新渲染。那么我们就需要先知道有哪些操作可以导致回流:
以下操作会触发回流:
1、调整窗口大小
2、改变字体
3、增加或者移除样式表
4、内容变化,比如用户在input框中输入文字
5、激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活
6、操作 class 属性
7、脚本操作 DOM
8、计算 offsetWidth 和 offsetHeight 属性
9、设置 style 属性的值
10、其他会导致回流的操作
所以就有了以下失败的尝试:
给body顶部插入元素,设定body的宽度,设定绝对定位再设置回来,强制修改font-face的字体再改回来等等,最终解决是没成功,如果各位有什么好办法欢迎留言。
解决方案3:重设font-face的伪类内容
最终通过设置 !important 来覆盖所有font-face的css,再重新应用就可以实现了。
代码:
<style>
html.fix-ie-font-face :before,
html.fix-ie-font-face :after {
content: none !important;
}
</style>
<script>
//重设伪类,使字体强制生效
!(function redrawFontFace() {
if ($.support.leadingWhitespace) return;
$(window).one("load", function() {
console.log("onload!!!!!!!!!!!");
$('html').addClass('fix-ie-font-face');
setTimeout(function() {
$('html').removeClass('fix-ie-font-face');
}, 10);
});
}());
</script>
原理就是先让所有图标字体失效,再让他们生效,就可以了。
需要注意的一点是:必须注册为 window 的 onload 事件。
最常用的$.ready()是不行的,他的本质是 DOMContentLoaded ,他会在DOM加载结束后就触发,我们需要在图标字体文件加载后再执行,因为没有字体加载后的load事件(如果有请一定告诉我),所以必须要在整页所有资源都加载完成后再触发本函数。
顺便附上jquery中的 $.ready 实现方法源码:
//jquery-1.9.1.js #885
jQuery.ready.promise = function( obj ) {
if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred.
// we once tried to use readyState "interactive" here, but it caused issues like the one
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready ); // Standards-based browsers support DOMContentLoaded
} else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed, false ); // A fallback to window.onload, that will always work
window.addEventListener( "load", completed, false ); // If IE event model is used
} else {
// Ensure firing before onload, maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work
window.attachEvent( "onload", completed ); // If IE and not a frame
// continually check to see if the document is ready
var top = false; try {
top = window.frameElement == null && document.documentElement;
} catch(e) {} if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) { try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
} // detach all dom ready events
detach(); // and execute any waiting functions
jQuery.ready();
}
})();
}
}
}
return readyList.promise( obj );
};
$.ready的源码
其他问题
1、IE8下图标字体非常有锯齿感怎么解决?如图

解决方案:做一张1*1大小的透明PNG图,然后给所有的图标字体的类样式增加IE特有的 filter 属性,如下:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=images/IEfix.png, sizingMethod=crop);
zoom: 1;
增加滤镜后效果:

图标看上去还算说得过去,至于文字的锯齿,不是本文探讨的范围内,辣个要去电脑中设置了。
缺点就是会降低页面打开速度,增加页面CPU占用量,会让页面变卡,当然前提是你页面使用了太多图标字体。
2、待补充…
代码下载
本文代码已托管至Github:
https://github.com/xxcanghai/cnblogsFiles/tree/master/fix-IE-bootstrap-font-face
扩展阅读
(完)
原文地址-http://www.cnblogs.com/xxcanghai/p/5000984.html
老爷车IE8如何兼容图标字体的更多相关文章
- 图标字体 VS 雪碧图——图标字体应用实践
本文介绍使用图标字体和SVG取代雪碧图的方法.雪碧图是很多网站经常用到的一种技术,但是它有缺点:高清屏会模糊.无法动态变化如hover时候反色.而使用图标字体可以完美解决上述问题,同时具备兼容性好,生 ...
- 图标字体(IconFont)制作
图标字体(IconFont)介绍 图标字体(IconFont)现在越来越被广泛使用,大大提高了网页的多样化,解决了视网膜屏幕失真的问题. 据说微软从IE4开始支持的这个私有方法(@font-face) ...
- 学习WPF——使用Font-Awesome图标字体
图标字体介绍 在介绍图标字体之前,不得不介绍图标格式ICON ICON是一种图标格式,我们操作系统中各种应用程序都包含一个图标 比如QQ程序的图标是一个可爱的企鹅,我的电脑是一个显示器图标 ----- ...
- 图标字体的使用(fontello.com)字体推荐及使用技巧
网页设计中为了页面漂亮好看,图标是少不了,网页中使用的图标通常都是使用图片,使用图片图标的有很多弊端,如果你经常制作网页应该有一肚子埋怨. 使用图片图标的弊端 放大图标必须重新作图, 改变颜色必须开启 ...
- iocfont 网页图标字体以及使用方法
在网页设计中使用图标字体(icon font)是件挺有新意的事情,使用图标字体能我们带来了一定的方便,比如在移动设备.Retina屏幕效果展示.兼容IE6/7浏览器以及能任意将图标放大缩小等,这些都是 ...
- CSS高级技巧 图标字体ICONFONT的使用方法视频
图标字体 iconfont 这是一种字体,它跟svg 有很大 相似点 它是矢量的,放大缩小不失真的.很且很小. 我们把它成字看来. 字体 在 从ie4就开始支持的. 兼容性很好 唯一麻烦的地方 ...
- (转载)app ico图标字体制作
图标字体化浅谈 在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复 ...
- DIV+CSS IE6/IE7/IE8/FF兼容问题汇总
1.IE8下兼容问题,这个最好处理,转化成ie7兼容就可以.在头部加如下一段代码,然后只要在IE7下兼容了,IE8下面也就兼容了 <meta http-equiv="x-ua-comp ...
- 如何灵活利用免费开源图标字体-IcoMoon篇——张鑫旭
一.温故知新 之前有专门介绍过如何使用类似fontforge软件制作自定义字符字体以及如何在web中实际应用. 不过,文中提到的是利用系统自带的一些特殊字体,如WINGDNG3.ttf字体. 显然,系 ...
随机推荐
- SQL 注入防御方法总结
SQL 注入是一类危害极大的攻击形式.虽然危害很大,但是防御却远远没有XSS那么困难. SQL 注入可以参见:https://en.wikipedia.org/wiki/SQL_injection S ...
- java微信接口之三—上传多媒体文件
一.微信上传多媒体接口简介 1.请求:该请求是使用post提交from来实现的,我们可以在网页上进行表单提交来实现.地址为: http://file.api.weixin.qq.com/cgi-bin ...
- MySQL单机多实例安装并配置主从复制
单机多实例据说可以最大程度提高硬件使用,谁知道呢,但是以前的公司喜欢这样搞,我最近也在学习复制什么的,电脑搞不起两台虚拟机,刚好单机多实例可以解救我.下面就说说步骤. 承上文http://www.cn ...
- python enumerate 函数用法
enumerate字典上是枚举.列举的意思. C语言中关键字enum也是enumerate的缩写. python中enumerate方法,返回一个enumerate类型.参数一般是可以遍历的的 ...
- SQL 分页查询的四种方法
方法一 假设现在有这样的一张表: CREATE TABLE test ( id int primary key not null identity, names ) ) 然后向里面插入大约100条数据 ...
- CocurrentHashMap和Hashtable的区别
集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性能,而不再需要过时的Vector了,等等.JDK 1.5引入了一些好用的并发 ...
- 实用图像处理入门 - 2 - Windows平台下编译openCV
标签中的部分 font-family: 华文细黑; font-size: 26px; font-weight: bold; color: #611427; margin-top:40px; } h2 ...
- 边工作边刷题:70天一遍leetcode: day 70
Design Phone Directory 要点:坑爹的一题,扩展的话类似LRU,但是本题的accept解直接一个set搞定 https://repl.it/Cu0j # Design a Phon ...
- 基于对话框的MFC应用程序基本结构
新建一个基于对话框的MFC应用程序,假设命名为 Test:则该应用程序在刚创建的时候,有4个非常重要的文件和3个类: 4个非常重要的文件 1.Test.h 2.Test.cpp (应用程序类头文件) ...
- HDU 2065 “红色病毒”问题 --指数型母函数
这种有限制的类棋盘着色问题一般可以用指数型母函数来解决,设Hn表示这样的着色数,首先H0=1,则Hn等于四个字母的(A,B,C,D)的多重集合的n排列数,其中每个字母的重数是无穷,且要求A,C出现的次 ...