24
2012
ZZ 您还在为XP系统下的微软雅黑烦脑吗?
转自HTML5集中营
由于公司网站的字体是用的「微软雅黑」,使用Windows XP的用户看到的页面字体颜色淡淡的,辨识度不是很好,于是我百度寻找解决方案,在百度得到的答案是”因为Windows XP 默认没有开启Clear Type,所以不支持字体渲染才会造成页面字体不太适合阅读,会觉得淡淡的颜色不够深,看起来不是很友好,辨识度还比宋体差很多。如下图:
难道我们要让用户手动去开启Clear Type,我想这也太不现实了吧!为了解决这个问题,我苦恼了很久,相信这也是很多前端工程师和设计师们一直纠结而痛苦的问题,就这样放弃其实又感觉蛮可惜的,因为「微软雅黑」字型漂亮,浏览网页看比宋体的网页要舒服很多,也会漂亮很多,心情也会愉悦起来。即然前端工程师和设计师都很喜欢微软雅黑,那么我们应该如何解决呢?直到我偶然发现了点点网,浏览完整个博客感触很深,因为他们的前端做得很细腻,细节处理惩罚得很好,于是我拜读一下点点网的代码。
其初,看CSS样式表没有任何的区别,很正常的都是调用的 font:normal 12px/1.5 “Helvetica Neue”,”Hiragino Sans GB”,”Segoe UI”,”Microsoft Yahei”,”微软雅黑”,也就没有太在意,后来我用Windows XP系统看了一下,发现他的html标签上添加了一个类:hasFontSmoothing-false,这个类的具体内容是: font:normal 12px/1.5 “宋体”,Tahoma,Arial,Helvetica,STHeiti;
然后问题来了,怎么才能知道浏览器是否支持Clear Type呢?你懂得,Google或百度一下,于是我得到以下答案:
很多人的系统其实是可以使用「微软雅黑」来浏览网页,但是却因为需要像下兼容,默认给了他们宋体,要处理这个问题,最好的方法就是照渐进增强的原则,有支持字型渲染的给他「微软雅黑」,没支持的给他宋体,IE的解决方案很简单,一句screen.fontSmoothingEnabled就搞定,不过其他几个浏览器就只能有哭的份了。
还好HTML5的canvas发展到了可以在里面画字,而这部份的功能其他几家浏览器都实作的比较快,于是就想到用这个功能来判断系统有没有支援字体渲染,作法就是先用到处都有的字型画个字进去,然后再看几个关键点的颜色来判断,如果有支持的话它就会在 html 标签加上hasFontSmoothing-true这个 class。
然后重新分析了一下这个需示:
如果系统支持 Clear Type,那就用微软雅黑做预设字型(sans-serif)
不支持的话,用新细明体(serif)
假如无法判断就当成没有 Clear Type
不支持 JavaScript 的情形当成没有 Clear Type
然后考虑到系统环境,事实上只有 Windows 需要做这个判断,OSX 不用说自然是都有,Linux 虽然不一定,但是它并没有宋体和微软雅黑字体的选择问题,所以只要考虑 Windows XP下的情形,有没有 Clear Type 和有没有安装微软雅黑,最后在CSs样式表里添加一行代码就是了:
- html {
- font:normal 12px/1.5 “宋体”,Tahoma,Arial,Helvetica,STHeiti;
- }
- html.hasFontSmoothing-true {
- font:normal 12px/1.5 “Helvetica Neue”,”Hiragino Sans GB”,”Segoe UI”,”Microsoft
- }
hasFontSmoothing脚本文件:
- var TypeHelpers = new function(){
- // I use me instead of this. For reasons why, please read:
- // http://w3future.com/html/stories/callbacks.xml
- var me = this;
- me.hasSmoothing = function(){
- // IE has screen.fontSmoothingEnabled – sweet!
- if (typeof(screen.fontSmoothingEnabled) != “undefined”) {
- return screen.fontSmoothingEnabled;
- } else {
- try {
- // Create a 35×35 Canvas block.
- var canvasNode = document.createElement(‘canvas’);
- canvasNode.width = “35”;
- canvasNode.height = “35”
- // We must put this node into the body, otherwise
- // Safari Windows does not report correctly.
- canvasNode.style.display = ‘none’;
- document.body.appendChild(canvasNode);
- var ctx = canvasNode.getContext(‘2d’);
- // draw a black letter ‘O’, 32px Arial.
- ctx.textBaseline = “top”;
- ctx.font = “32px Arial”;
- ctx.fillStyle = “black”;
- ctx.strokeStyle = “black”;
- ctx.fillText(“O”, 0, 0);
- // start at (8,1) and search the canvas from left to right,
- // top to bottom to see if we can find a non-black pixel. If
- // so we return true.
- for (var j = 8; j <= 32; j++) {
- for (var i = 1; i <= 32; i++) {
- var imageData = ctx.getImageData(i, j, 1, 1).data;
- var alpha = imageData[3];
- if (alpha != 255 && alpha != 0) {
- return true; // font-smoothing must be on.
- }
- }
- }
- // didn’t find any non-black pixels – return false.
- return false;
- }
- catch (ex) {
- // Something went wrong (for example, Opera cannot use the
- // canvas fillText() method. Return null (unknown).
- return null;
- }
- }
- }
- me.insertClasses = function(){
- var result = me.hasSmoothing();
- var htmlNode = document.getElementsByTagName(‘html’)[0];
- if (result == true) {
- htmlNode.className += ” hasFontSmoothing-true”;
- } else if (result == false) {
- htmlNode.className += ” hasFontSmoothing-false”;
- } else { // result == null
- htmlNode.className += ” hasFontSmoothing-unknown”;
- }
- }
- }
- // if EventHelpers.js is included, insert the hasFontSmoothing CSS classes
- if (window.EventHelpers) {
- EventHelpers.addPageLoadEvent(‘TypeHelpers.insertClasses’)
- }
但是以上要注意了,有这样一段注释
- // if EventHelpers.js is included, insert the hasFontSmoothing CSS classes
意思是说你需要EventHelpers.js,我打开看了一下,代码很多。
我按着自己的需要,删改了hasFontSmoothing.js,修改如下
- var TypeHelpers = new function(){
- var me = this;
- me.hasSmoothing = function(){
- // IE has screen.fontSmoothingEnabled – sweet!
- if (typeof(screen.fontSmoothingEnabled) != “undefined”) {
- return screen.fontSmoothingEnabled;
- } else {
- try {
- // Create a 35×35 Canvas block.
- var canvasNode = document.createElement(“canvas”);
- canvasNode.width = “35”;
- canvasNode.height = “35”
- // We must put this node into the body, otherwise
- // Safari Windows does not report correctly.
- canvasNode.style.display = “none”;
- document.body.appendChild(canvasNode);
- var ctx = canvasNode.getContext(“2d”);
- // draw a black letter “O”, 32px Arial.
- ctx.textBaseline = “top”;
- ctx.font = “32px Arial”;
- ctx.fillStyle = “black”;
- ctx.strokeStyle = “black”;
- ctx.fillText(“O”, 0, 0);
- // start at (8,1) and search the canvas from left to right,
- // top to bottom to see if we can find a non-black pixel. If
- // so we return true.
- for (var j = 8; j <= 32; j++) {
- for (var i = 1; i <= 32; i++) {
- var imageData = ctx.getImageData(i, j, 1, 1).data
- var alpha = imageData[3];
- if (alpha != 255 && alpha != 0 && alpha > 180) {
- return true; // font-smoothing must be on.
- }
- }
- }
- // didn’t find any non-black pixels – return false.
- return false;
- }
- catch (ex) {
- // Something went wrong (for example, Opera cannot use the
- // canvas fillText() method. Return null (unknown).
- return null;
- }
- }
- }
- addEvent(document,’DOMContentLoaded’, function () {
- var result = me.hasSmoothing(),
- html = document.getElementsByTagName(‘html’)[0],
- className = html.className;
- if (result == true) {
- html.className = className + ‘ hasFontSmoothing-true’;
- } else if (result == false) {
- html.className = className + ‘ hasFontSmoothing-false’;
- } else { // result == null
- html.className = className + ‘ hasFontSmoothing-unknown’;
- }
- }, false);
- }
- function addEvent(obj,sEvent,fn){
- obj.attachEvent ? obj.attachEvent(‘on’ + sEvent,fn) : addEventListener(sEvent,fn,false);
- }
参考的地址:hasFontSmoothing.js