web界面上的字体兼容方案
原贴地址:http://www.baidufe.com/item/60cd11d3bfdee5c51369.html
做前端的,对web界面基本都抠的很仔细,尤其精确到1px!
类似边距、宽度、高度等的,调整1px并不难,但是如果遇到不同字体的情况,要处理line-height,保证每种字体下,UI效果都非常美观,这就不是一件简单的事情了!
也许大家首先能想到的是,字体嘛,默认给页面body节点设置一个font-family列表即可:
body {
font-size: 12px;
font-family:"Microsoft Yahei", "微软雅黑", Tahoma, Arial, Helvetica, STHeiti;
}
但其实问题并没有这么简单,font-family列表是必然要设置的,但这个列表的具体解析,只有浏览器自己才知道,如果coder们不在这个基础上做点儿什么,是完全不知道某个用户浏览到的这个页面究竟应用到了那种字体、此时的页面排版是否美观、页面有没有出现文字很拥挤的情况、给某个节点设置的背景icon是否对其了?
等等,各种问题,各种猜测。。。
实际开发中,这也确实是一个问题,作为专业coder,是需要兼容各个细节的,包括这里的字体控制。
任务:
利用Javascript编写一个组件,用于检测某用户浏览页面时,浏览器应用到了那种字体(以微软雅黑为例)。
问题:
1、用户机器未安装雅黑字体时,需要用别的字体替代,并且要对其他样式进行修正
2、用户机器安装了雅黑字体时:
a、用户机器未开启ClearType时,雅黑字体显示出来会有锯齿,此时依然要将页面字体设置为默认,并同样对其他样式进行修正
b、用户机器开启了ClearType时,按照正常的模式进行渲染,不需要对其他样式进行修正
方法:
1、页面开始渲染时,检测用户机器上是否安装了雅黑字体
2、检测用户机器是否开启了ClearType
3、如果一切如愿,给html节点增加class="ms-with-yahei",否则增加class="ms-without-yahei"
4、样式修正:对html.ms-without-yahei下的样式进行复写
实现:
只要这一切都分析好了,要实现,就很简单了,核心的部分代码就是:
1、检测用户机器是否安装了某种字体:
a、IE浏览器中,通过创建<object classid="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b"></object>,直接访问系统的字体库,读取字体列表,判断某种字体是否存在
if(qing.browser.ie){
_dlgHelper = qing.dom.create('object',{
id : "sp-font-detect-obj",
classid : "clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b"
});
qing.dom.setStyles(_dlgHelper,{
"position": "absolute",
"top": "-10000px",
"left": "-10000px",
"width" : "1px",
"height" : "1px"
});
document.body.appendChild(_dlgHelper);
_isInitialedInIE = true;
}
//IE中,用object的classid来判断字体
if(qing.browser.ie) {
if(!_isInitialedInIE) {
init();
}
var sysFonts = _dlgHelper.fonts;
if(sysFonts.count) {
for(var i = 1,len = sysFonts.count;i <= len;i++){
if(isInArray(sysFonts(i),familys)) {
return callback(true);
}
}
}
return callback(false);
}
b、非IE的浏览器中,创建一个span标签,再插入一段字符,设置很大的字号和默认字体(预计所有机器都有的“Times New Roman”),获取到span的offsetWidth;再给span追加一个待检测的字体,再获取其offsetWidth;两个width进行比较,如果相同,则表明用户机器没有这种字体,否则表明用户机器确实安装了这种字体!
/**
* 检查字体宽度
* @param {Object} family
*/
var checkOffsetWidth = function(family){
var node = document.createElement("p");
qing.dom.setStyles(node, {
"font-family": family + ", Times New Roman",
"font-size": '300pt',
"display": "inline",
"position": "absolute",
"top": "-10000px",
"left": "-10000px"
});
qing.dom.addClass(node, "sp-font-detect");
node.innerHTML = "mmmmmmmmml";
document.body.appendChild(node); var width = node.offsetWidth;
document.body.removeChild(node);
return width;
};
/**
* 获取文字实际宽度
*/
var getDefaultWidth = function(){
if (!_defaultWidth)
_defaultWidth = checkOffsetWidth("Times New Roman");
return _defaultWidth;
};
//非IE浏览器中,用比较宽度的方法来判断
else{
var familyWidth = 0;
var defaultWidth = getDefaultWidth();
for(var j = 0,flen = familys.length;j < flen;j++){
familyWidth = checkOffsetWidth(familys[j]);
if(familyWidth !== defaultWidth){
return callback(true);
}
}
return callback(false);
}
2、检测用户机器是否开启了ClearType
a、IE下,直接通过screen.fontSmoothingEnabled获取
b、非IE下,创建canvas,画一条粗线,然后获取并分析该DataURI数据
/**
* 是否开启了clearType
*@function isClearTypeOn
*@return {Boolean} 如果支持,显示true;否则返回false
*/
var isClearTypeOn = function() {
if(typeof screen.fontSmoothingEnabled!="undefined")
return screen.fontSmoothingEnabled;
else
try {
var f=document.createElement("canvas");
f.width="35";
f.height="35";
f.style.display="none";
document.body.appendChild(f);
var o=f.getContext("2d");
o.textBaseline="top";
o.font="32px Arial";
o.fillStyle="black";
o.strokeStyle="black";
o.fillText("E",0,0);
for(var r=8;r<=32;r++)
for(var u=1;u<=32;u++) {
var q=o.getImageData(u,r,1,1).data[3];
if(q != 255 && q != 0) {
document.body.removeChild(f);
return true
}
}
document.body.removeChild(f);
return false
} catch(y) {
return null
}
};
3、在css中定义“其他字体情况下,样式的修复方案”
body, button, input, select, textarea , pre {
font-size: 12px;
font-family:"Microsoft Yahei", "微软雅黑", Tahoma, Arial, Helvetica, STHeiti;
_font-family:Tahoma,Arial,Helvetica,STHeiti;
}
html.mod-without-msyahei body {
font-family: Tahoma,Arial,Helvetica,STHeiti;
}
/****************系统默认支持雅黑的处理**********************/
.mod-without-msyahei .mod-blogitem .a-expand-reason{
background-position-y:-15px;
}
.mod-without-msyahei .mod-blogitem .a-collapse-reason{
background-position-y:3px;
}
.mod-without-msyahei .mod-blogitem .box-tag .q-tag{
_padding:5px 3px 1px;
}
.mod-without-msyahei .mod-blogitem .item-head .q-private {
line-height:23px;
_padding-top:3px;
}
4、在页面上,调用detect方法进行字体检测,并进行样式纠偏
/**
* 字体监测
* @return {[type]}
*/
var _fontDetect = function(){
qext.FontDetect.detect(['微软雅黑','Microsoft Yahei'],function(isExist){
//获得html节点
var htmlElm = qing.dom.query('html')[0];
//开启clearType并存在雅黑字体
if(isExist){
qing.dom.addClass(htmlElm,'mod-with-msyahei');
}else{
qing.dom.addClass(htmlElm,'mod-without-msyahei');
}
});
};
这样,就能保证整个页面在不同的字体情况下,UI展现都尽量保持一致性!
web界面上的字体兼容方案的更多相关文章
- 基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在之前的一篇文章<Winform开发框架之通用数据导入导出操作>介绍了在Winform ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
http://www.cnblogs.com/wuhuacong/p/3873498.html 数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面
最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重 ...
- CentOS6.8下搭建zookeeper web界面查看工具node-zk-browser
zookeeper的web界面查看工具Node-ZK-Browser的界面是用nodejs写的今天试着搭建了下. 1. 安装nodejs [root@localhost product]# pwd / ...
- 让IE8支持HTML5及canvas功能!chart.js图表绘制工具库IE8上兼容方案
第一步,我们加上对html5的支持. <!--[if IE]> <script src="/public/html5.js" type="text/ja ...
- ASP.NET 开发必备知识点(1):如何让Asp.net网站运行在自定义的Web服务器上
一.前言 大家都知道,在之前,我们Asp.net 的网站都只能部署在IIS上,并且IIS也只存在于Windows上,这样Asp.net开发的网站就难以做到跨平台.由于微软的各项技术的开源,所以微软自然 ...
- Open Sans字体兼容问题解决办法[font-face]
参考:http://www.tantengvip.com/2014/11/open-sans/ 1.font-face使用方法 font-face是CSS3中的一个模块,主要是把自定义的Web字体嵌入 ...
- 移动Web应用开发入门指南——兼容篇
兼容篇 兼容篇是我最想写的一部分,在这之前也总结过很多关于移动开发的兼容问题与解决方案.对于移动Web开发来说,兼容是开发重心,通常要花费30%甚至更多的时间去处理一些兼容问题,甚至时间花掉了,问题依 ...
- Emoji表情符号兼容方案(适用ios,android,wp等平台)
http://blog.csdn.net/qdkfriend/article/details/7576524 Emoji表情符号兼容方案 一 什么是Emoji emoji就是表情符号:词义来自日语(え ...
随机推荐
- Application的作用
Application可实现数据共享 例如: 一.新建一个空的工程,并新建一个App类,继承自Application public class App extends Application { pr ...
- About toupper()
// toupper.c #include <stdio.h> #include <string.h> #include <ctype.h> int main() ...
- HAWQ取代传统数仓实践(七)——维度表技术之维度子集
有些需求不需要最细节的数据.例如更想要某个月的销售汇总,而不是某天的数据.再比如相对于全部的销售数据,可能对某些特定状态的数据更感兴趣等.此时事实数据需要关联到特定的维度,这些特定维度包含在从细节维度 ...
- [转]页游开发中的 Python 组件与模式Presentation Transcript
转: 页游开发中的 Python 组件与模式Presentation Transcript 1. 页游开发中的 Python 组件与模式 赖勇浩( http://laiyonghao.com ) 20 ...
- Windows手动安装Apache,MySql服务
绿色版的Apache,Mysql需要以服务方式运行.或者由于某种原因服务管理器里面没有服务项了,可以进行手工注册服务和启并服务. # Apache Apache进到安装目录的bin目录下,运行dos命 ...
- nginx time_wait 较多优化
1. 查看命令 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 结果 ESTABLISHED 22 F ...
- 简述MVC模式
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- 数据立方体----维度与OLAP
前面的一篇文章——数据仓库的多维数据模型中已经简单介绍过多维模型的定义和结构,以及事实表(Fact Table)和维表(Dimension Table)的概念.多维数据模型作为一种新的逻辑模型赋予了数 ...
- wordpress更换域名
问题缘由 在群里面看到很多朋友问,wordpress要换域名这么办?后台的设置-常规里修改里域名后,全站打不开了,这是为什么?这么办? 问题解说 其实wordpress换域名需要到数据库进行操作的,首 ...
- 15.Selenium+Python滑动解锁小案例
1.代码实现 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChai ...