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就是表情符号:词义来自日语(え ...
随机推荐
- Java 面试/笔试题神整理 [Java web and android]
Java 面试/笔试题神整理 一.Java web 相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并 ...
- Spring核心AOP(面向切面编程)总结
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75208354冷血之心的博客) 1.AOP概念: 面向切面编程,指扩 ...
- Python虚拟环境设置
Python2环境 首先,我们用pip安装virtualenv: pip3 install virtualenv 然后,假定我们要开发一个新的项目,需要一套独立的Python运行环境,可以这么做: 第 ...
- (七)java转译字符与连接字符串
转义字符:通过“\”来改变后面字符的意义 \n空格 \t相当于table键 \b相当于回退 class Zyzf { public static void main(String[] args) { ...
- bzoj 2131 免费的馅饼
Written with StackEdit. Description Input 第一行是用空格隔开的二个正整数,分别给出了舞台的宽度\(W\)(\(1\)到\(10^8\)之间)和馅饼的个数\(n ...
- RabbitMQ学习系列四-EasyNetQ文档跟进式学习与实践
EasyNetQ文档跟进式学习与实践 https://www.cnblogs.com/DjlNet/p/7603554.html 这里可能有人要问了,为什么不使用官方的nuget包呐:RabbitMQ ...
- LG2120 [ZJOI2007]仓库建设
题意 L公司有N个工厂,由高到底分布在一座山上. 工厂1在山顶,工厂N在山脚. 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用. 突然有一天,L公司的总裁L先生接到 ...
- docker 命令记录
从 Docker 镜像仓库获取镜像的命令是 docker pull.其命令格式为: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 具体的选项 ...
- php通过存储过程传入汉字参数并写入数据库
写入数据库,汉字为???样式的乱码,后根据网上介绍的方法,参数前加N,数据库汉字内容变成空白. 解决方法,在PHP中先转为base64,再在mysql中base64解码,前提先保证mysql中有bas ...
- laravel 二维码生成器包 QrCode 的使用
在laravel中使用 QrCode 生成二维码 https://laravelacademy.org/post/2605.html 我在本机的windows下composer require 没有成 ...