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就是表情符号:词义来自日语(え ...
随机推荐
- CentOS7 编译安装golang和rpm安装golang
编译安装 1.下载golang二进制安装包: https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz 2.解压安装包到指定目录,此 ...
- VMware Workstation/Fusion 14/15 密钥
VMware WorkStation 14 CG54H-D8D0H-H8DHY-C6X7X-N2KG6 ZC3WK-AFXEK-488JP-A7MQX-XL8YF AC5XK-0ZD4H-088HP- ...
- [leetcode]_Validate Binary Search Tree
题目:判断一棵二叉树是否合法.要求二叉树满足 左子树所有值 < 当前值 < 右子树所有值,并且所有点都满足这个条件. 思路: 1.从当前根节点判断,求根节点左子树最大值maxLeft,右子 ...
- MySql必知必会实战练习(四)主键、外键、sql约束、联结表
本博将对主键.外键.MySql数据库约束和联结表的相关特性进行总结和实战 1. 主键 表中的每一行都应该具有可以唯一标识自己的一列(或一组列),而这个承担标识作用的列称为主键 如果没有主键,数据的管理 ...
- 快速沃尔什变换FWT
快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...
- UITextField的使用总结
初始化一个文字框: UITextField * textField = [[UITextField alloc]initWithFrame:CGRectMake(, , , )]; 设置和获取文字框文 ...
- 关于verilog中小数直接赋值
verilog中小数直接赋值的话小数会近似成1,如0.1,0.6,0.9赋值的话就会变成1,5.1,5.9也都会变成6.并且quartus默认小数是64位.
- 一般在cmd中报不是合法的命令啥的,都是环境变量没有配置好
在配置cnpm的时候一定要将环境变量先配置好,配置如下: C:\Program Files\nodejs; C:\Program Files\nodejs\node_global; C:\Progra ...
- VC++中如何让RadioButton分组,并且互斥
首先让两个RadioButton的Group属性为False. 将两个RadioButton放入一个GroupBox里面,即可如果分成多个组,则将多组Radio分别用GroupBox框起来,并将每组的 ...
- How to get the MD5 checksum for a file: md5sum, digest, csum, fciv
LINUX: md5sum fileName In Linux, the md5sum utility can be used: aemtux1:/ % md5sum binary.file 0c46 ...