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展現都盡量保持一致性!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM