8月
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样式表里添加一行代码就是了:

  1. html {
  2.     font:normal 12px/1.5 “宋体”,Tahoma,Arial,Helvetica,STHeiti;
  3. }
  4. html.hasFontSmoothing-true {
  5.    font:normal 12px/1.5 “Helvetica Neue”,”Hiragino Sans GB”,”Segoe UI”,”Microsoft
  6. }

hasFontSmoothing脚本文件:

  1. var TypeHelpers = new function(){
  2.    // I use me instead of this.  For reasons why, please read:
  3.    // http://w3future.com/html/stories/callbacks.xml
  4.    var me = this;
  5.    me.hasSmoothing = function(){
  6.       // IE has screen.fontSmoothingEnabled – sweet!
  7.       if (typeof(screen.fontSmoothingEnabled) != “undefined”) {
  8.          return screen.fontSmoothingEnabled;
  9.       } else {
  10.          try {
  11.             // Create a 35×35 Canvas block.
  12.             var canvasNode = document.createElement(‘canvas’);
  13.             canvasNode.width = “35”;
  14.             canvasNode.height = “35”
  15.             // We must put this node into the body, otherwise
  16.             // Safari Windows does not report correctly.
  17.             canvasNode.style.display = ‘none’;
  18.             document.body.appendChild(canvasNode);
  19.             var ctx = canvasNode.getContext(‘2d’);
  20.             // draw a black letter ‘O’, 32px Arial.
  21.             ctx.textBaseline = “top”;
  22.             ctx.font = “32px Arial”;
  23.             ctx.fillStyle = “black”;
  24.             ctx.strokeStyle = “black”;
  25.             ctx.fillText(“O”, 0, 0);
  26.             // start at (8,1) and search the canvas from left to right,
  27.             // top to bottom to see if we can find a non-black pixel.  If
  28.             // so we return true.
  29.             for (var j = 8; j <= 32; j++) {
  30.                for (var i = 1; i <= 32; i++) {
  31.                   var imageData = ctx.getImageData(i, j, 1, 1).data;
  32.                   var alpha = imageData[3];
  33.                   if (alpha != 255 && alpha != 0) {
  34.                      return true; // font-smoothing must be on.
  35.                   }
  36.                }
  37.             }
  38.             // didn’t find any non-black pixels – return false.
  39.             return false;
  40.          }
  41.          catch (ex) {
  42.             // Something went wrong (for example, Opera cannot use the
  43.             // canvas fillText() method.  Return null (unknown).
  44.             return null;
  45.          }
  46.       }
  47.    }
  48.    me.insertClasses = function(){
  49.       var result = me.hasSmoothing();
  50.       var htmlNode = document.getElementsByTagName(‘html’)[0];
  51.       if (result == true) {
  52.          htmlNode.className += ” hasFontSmoothing-true”;
  53.       } else if (result == false) {
  54.             htmlNode.className += ” hasFontSmoothing-false”;
  55.       } else { // result == null
  56.             htmlNode.className += ” hasFontSmoothing-unknown”;
  57.       }
  58.    }
  59. }
  60. // if EventHelpers.js is included, insert the hasFontSmoothing CSS classes
  61. if (window.EventHelpers) {
  62.    EventHelpers.addPageLoadEvent(‘TypeHelpers.insertClasses’)
  63. }

但是以上要注意了,有这样一段注释

  1. // if EventHelpers.js is included, insert the hasFontSmoothing CSS classes

意思是说你需要EventHelpers.js,我打开看了一下,代码很多。

我按着自己的需要,删改了hasFontSmoothing.js,修改如下

  1. var TypeHelpers = new function(){
  2.   var me = this;
  3.   me.hasSmoothing = function(){
  4.     // IE has screen.fontSmoothingEnabled – sweet!
  5.     if (typeof(screen.fontSmoothingEnabled) != “undefined”) {
  6.       return screen.fontSmoothingEnabled;
  7.     } else {
  8.         try {
  9.       // Create a 35×35 Canvas block.
  10.         var canvasNode = document.createElement(“canvas”);
  11.         canvasNode.width = “35”;
  12.         canvasNode.height = “35”
  13.         // We must put this node into the body, otherwise
  14.         // Safari Windows does not report correctly.
  15.         canvasNode.style.display = “none”;
  16.         document.body.appendChild(canvasNode);
  17.         var ctx = canvasNode.getContext(“2d”);
  18.         // draw a black letter “O”, 32px Arial.
  19.         ctx.textBaseline = “top”;
  20.         ctx.font = “32px Arial”;
  21.         ctx.fillStyle = “black”;
  22.         ctx.strokeStyle = “black”;
  23.         ctx.fillText(“O”, 0, 0);
  24.         // start at (8,1) and search the canvas from left to right,
  25.         // top to bottom to see if we can find a non-black pixel.  If
  26.         // so we return true.
  27.         for (var j = 8; j <= 32; j++) {
  28.           for (var i = 1; i <= 32; i++) {
  29.             var imageData = ctx.getImageData(i, j, 1, 1).data
  30.             var alpha = imageData[3];
  31.             if (alpha != 255 && alpha != 0 && alpha > 180) {
  32.               return true; // font-smoothing must be on.
  33.               }
  34.             }
  35.           }
  36.           // didn’t find any non-black pixels – return false.
  37.           return false;
  38.         }
  39.         catch (ex) {
  40.           // Something went wrong (for example, Opera cannot use the
  41.           // canvas fillText() method.  Return null (unknown).
  42.           return null;
  43.         }
  44.       }
  45.     }
  46.   addEvent(document,’DOMContentLoaded’, function () {
  47.     var result = me.hasSmoothing(),
  48.         html = document.getElementsByTagName(‘html’)[0],
  49.         className = html.className;
  50.     if (result == true) {
  51.       html.className = className + ‘ hasFontSmoothing-true’;
  52.     } else if (result == false) {
  53.       html.className = className + ‘ hasFontSmoothing-false’;
  54.     } else { // result == null
  55.       html.className = className + ‘ hasFontSmoothing-unknown’;
  56.     }
  57.   }, false);
  58. }
  59. function addEvent(obj,sEvent,fn){
  60.     obj.attachEvent ?  obj.attachEvent(‘on’ + sEvent,fn) : addEventListener(sEvent,fn,false);
  61. }

参考的地址:hasFontSmoothing.js

相关文章

关于作者:moface

博主

留下评论

博客剩余工作

6,优化前台(YSlow) 2,404页面 3,IE6下兼容性问题很大 1,标签小工具行高有点儿问题 4,微博聚合 5,推广工作 7,CDN(cloudflare

分类

访问统计