前言

首先这个标题再详细的说就是如何解决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:加载完成后调整下浏览器大小

大家应该都知道,调整浏览器大小会造成网页重绘回流,会让页面几乎所有元素重新绘制。因为重新绘制样式了,所以自然也就可以了解决图标字体渲染失败的问题。

缺点自然不用说,这等于没解决,不过我们可以利用重绘后图标生效的特性来让强制令其页面回流重绘。

关于不知道什么是回流与重绘的同学可以参考:链接1链接2

解决方案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

扩展阅读

1、页面重绘和回流以及优化

2、回流与重绘:CSS性能让JavaScript变慢?

3、IE8 CSS @font-face fonts only working for :before content on over and sometimes on refresh/hard refresh

4、再不知道字体图标就落伍啦!

5、Font Awesome

(完)

原文地址-http://www.cnblogs.com/xxcanghai/p/5000984.html

老爷车IE8如何兼容图标字体的更多相关文章

  1. 图标字体 VS 雪碧图——图标字体应用实践

    本文介绍使用图标字体和SVG取代雪碧图的方法.雪碧图是很多网站经常用到的一种技术,但是它有缺点:高清屏会模糊.无法动态变化如hover时候反色.而使用图标字体可以完美解决上述问题,同时具备兼容性好,生 ...

  2. 图标字体(IconFont)制作

    图标字体(IconFont)介绍 图标字体(IconFont)现在越来越被广泛使用,大大提高了网页的多样化,解决了视网膜屏幕失真的问题. 据说微软从IE4开始支持的这个私有方法(@font-face) ...

  3. 学习WPF——使用Font-Awesome图标字体

    图标字体介绍 在介绍图标字体之前,不得不介绍图标格式ICON ICON是一种图标格式,我们操作系统中各种应用程序都包含一个图标 比如QQ程序的图标是一个可爱的企鹅,我的电脑是一个显示器图标 ----- ...

  4. 图标字体的使用(fontello.com)字体推荐及使用技巧

    网页设计中为了页面漂亮好看,图标是少不了,网页中使用的图标通常都是使用图片,使用图片图标的有很多弊端,如果你经常制作网页应该有一肚子埋怨. 使用图片图标的弊端 放大图标必须重新作图, 改变颜色必须开启 ...

  5. iocfont 网页图标字体以及使用方法

    在网页设计中使用图标字体(icon font)是件挺有新意的事情,使用图标字体能我们带来了一定的方便,比如在移动设备.Retina屏幕效果展示.兼容IE6/7浏览器以及能任意将图标放大缩小等,这些都是 ...

  6. CSS高级技巧 图标字体ICONFONT的使用方法视频

    图标字体  iconfont 这是一种字体,它跟svg 有很大 相似点   它是矢量的,放大缩小不失真的.很且很小. 我们把它成字看来. 字体 在 从ie4就开始支持的.  兼容性很好 唯一麻烦的地方 ...

  7. (转载)app ico图标字体制作

    图标字体化浅谈   在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复 ...

  8. DIV+CSS IE6/IE7/IE8/FF兼容问题汇总

    1.IE8下兼容问题,这个最好处理,转化成ie7兼容就可以.在头部加如下一段代码,然后只要在IE7下兼容了,IE8下面也就兼容了 <meta http-equiv="x-ua-comp ...

  9. 如何灵活利用免费开源图标字体-IcoMoon篇——张鑫旭

    一.温故知新 之前有专门介绍过如何使用类似fontforge软件制作自定义字符字体以及如何在web中实际应用. 不过,文中提到的是利用系统自带的一些特殊字体,如WINGDNG3.ttf字体. 显然,系 ...

随机推荐

  1. 读书笔记——数据库的ADO开发总结

    基本上是对 ADO+开发指南.pdf 的摘抄和总结,以及个人心得. 文章末尾有<ADO+开发指南.pdf>的资源下载,附带个人批注. --------------------------- ...

  2. MySQL的诡异同步问题-重复执行一条relay-log

    MySQL的诡异同步问题 近期遇到一个诡异的MySQL同步问题,经过多方分析和定位后发现居然是由于备份引发的,非常的奇葩,特此记录一下整个问题的分析和定位过程. 现象 同事扩容的一台slave死活追不 ...

  3. Python 部署项目(Tomcat 容器)

    此前书写了多实例的 Tomcat 启动等操作的脚本,今天完善 Tomcat 多实例部署(本脚本只提供思路) 脚本内容: #!/usr/bin/env python # _*_coding:utf-8_ ...

  4. linux中如何查看进程对应的cpu使用情况?

    使用ps aux | grep <进程名>即可查看指定进程的cpu使用情况.

  5. python singleton

    方法一:用元类的方式实现一个singleton. liuxiaoyan@development:~/mysite$ cat Singleton.py class Singleton(type): &q ...

  6. pyhon之Tkinter实例化学习

    Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口,位Python的内置模块,直接import tkinter即可使用. 作为实践, 用Tkinter ...

  7. Jenkins插件hyper slaves源码分析

    1.public class HyperSlaves extends Plugin implements Describable<HyperSlaves> (1).init():初始化co ...

  8. 分析循环 Analysis of Loops-------geeksforgeeks 翻译

    之前我们讨论了渐进分析,最佳最坏平均情况的分析以及渐进符号.在这一篇中我们分析一下迭代的简单程序. 1. O(1): 如果程序中没有包含任何的循环,递归或者任何的非常数时间的函数,我们就说这个程序的时 ...

  9. POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...

  10. 第23章 SEH结构化异常处理(2)_编译器对系统SEH机制的封装

    23.2 编译器层面对系统SEH机制的封装 23.2.1 扩展的EXCEPTION_REGISTRATION级相关结构:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTIO ...