前言

首先这个标题再详细的说就是如何解决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. mysql基础操作学习笔记(2)----索引

    为什么要创建索引?     在此本人也带着相同的疑问,能够解释的仅仅是:为了减少数据库查询时所需要的速度.如果正常查询和索引查询所需时间相差很多倍时我们自然是需要索引的了. 想要知道结果,只能等我学得 ...

  2. nginx配置PATH_INFO模式

    我们可以使用PATH_INFO来代替Rewrite来实现伪静态页面, 另外不少PHP框架也使用PATH_INFO来作为路由载体 在Apache中, 当不加配置的时候, 对于PHP脚本, Accept ...

  3. MyCat 学习笔记 第八篇.数据分片 之 求摸运算分片

    1 应用场景 Mycat 自带了多套数据分片的机制,其实根据数值取摸应该是最简单的一种. 优点:数据离散概率较为平均,可以有效的提高应用的数据吞吐. 缺点:比较明显,后期数据运维与迁移比较困难.好在M ...

  4. 进制,原码VS补码

    进制 十,八,十六进制=>二进制 十进制=>二进制:辗转相除取余,10除2商5余0,5除2商2余1,2除2商1余0,1除2商0余1,So,10d=1010b 八进制=>二进制:每1位 ...

  5. 系统调用wait、waitpid和exec函数

    本文介绍了Linux下的进程的一些概念,并着重讲解了与Linux进程管理相关的重要系统调用wait,waitpid和exec函数族,辅助一些例程说明了它们的特点和使用方法. 1.7 背景 在前面的文章 ...

  6. Go

    一.简介 https://zh.wikipedia.org/wiki/Go 二.安装 1)低版本 http://blog.sina.com.cn/s/blog_59cc90640102xm8r.htm ...

  7. builder.properties

    请加上这句话: javacDefaultEncoding.. = UTF-8

  8. NOIP2008提高组火柴棒等式(模拟)——yhx

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...

  9. [linux]SSH公钥登录

    由于口令密码容易泄露,SSH公钥登录相比口令登录更加安全.SSH可以轻松使用非对称加密技术给两台机子订立契约,步骤如下: 第一步 本地机生成秘钥对 指令:ssh-keygen 功能:在本地(~/.ss ...

  10. codeforces 487C C. Prefix Product Sequence(构造+数论)

    题目链接: C. Prefix Product Sequence time limit per test 1 second memory limit per test 256 megabytes in ...