1. 程式人生 > >hta工具:從.css檔案中清理不使用的樣式類(id或class類)

hta工具:從.css檔案中清理不使用的樣式類(id或class類)

-----------程式碼----------

<!DOCTYPE html>
<html>
<head>
<title>清除不使用的樣式</title>
</head>
<body>
<iframe id="html"  application="yes" style="display:none;"></iframe>
選擇html檔案<input type="file" id="htmlPath" />選擇css檔案<input type="file" id="cssPath" /><button onclick="startCls();">開始整理</button><br/>
整理後css內容<textarea id="outCss" /></textarea>

<script>
function getObj(id) {
    return 'string' == typeof id ? document.getElementById(id) : id;
}

function startCls() {
    var hPath = getObj('htmlPath').value;
    var cPath = getObj('cssPath').value;
    
    if (!hPath || !cPath) {
        alert('請選擇css/html檔案');return;
    }
    
    if (!/\.html?$/i.test(hPath) || !/\.css$/i.test(cPath)) {
        alert('html檔案字尾必須是.html(htm)/css檔案字尾必須是.css');return;
    }
        
    getObj('html').src = hPath;
    cPath = setInterval(function() {
        if ('complete' == frames[0].document.readyState) {
            document.title = '載入完成';
            clearInterval(cPath);
            getChild(frames[0].document);
        }
    }, 500);
}

function getChild(doc){//獲取所有body內的標籤的id或class
    
    var allTag = doc.body.getElementsByTagName('*');
    window.allClass = {};
    var clas;
    
    for (var i = 0; i < allTag.length; i++) {
        window.allClass[allTag[i].className] = true;//記錄標籤名
        
        if (clas = (' ' + allTag[i].className + ' ').match(/ (\w+)(?= )/g) ) {//得到所有class
            for (var ii = 0; ii < clas.length; ii++) {
                window.allClass['.' + clas[ii].toString().replace(' ', '')] = true;
            }
        } else if (/^[a-z]\w*$/i.test(allTag[i].id)) {//只獲取以字母開始的id
            window.allClass['#' + allTag[i].id] = true;
        }
    }
    
    compace();
}

function compace() {//檢測class是否用上
    var utf = frames[0].document.charset.toLowerCase().indexOf('utf-8utf8') > -1 ? 1 : 0;//根據html的編碼開啟css檔案模式
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var r = 1;
    var c = 0;
    var r = fso.OpenTextFile(getObj('cssPath').value, r, c, utf);
    var css = r.readAll().replace(/\/\*[\s\S]*?\*\//g, '');//移除註釋;
    r.close();
    
    if (! (css = css.match(/[^\{\}]+\{[^\{\}]*\}/g))) {
        return alert('沒有存在class格式內容');
    }

    window.css = [];
    css[0] = css[0].replace(/(@charset [^;]+;)\s?/i, function($0, $1){//確定編碼
            window.css.push($1);//編碼
            return '';
        }
    );
    
    for (var vals, tmp, names, name, n, r, i = 0; i < css.length; i++) {
        vals = css[i].split('{');
        names = vals[0].split(',');//根據,號分開成多個name
        tmp = [];
        vals = clSpace('{' + vals[1]);//class規則
        
        for (var ii = 0; ii < names.length; ii++) {
            name = names[ii].replace(/^\s+|\s+$/g, '');//移除空格
            
            if ('*' == name) {//直接放回//針對所有標籤
                tmp.push(name);
            } else if (/^[a-z]/i.test(name)) {//指定標籤式,暫不做對比,可能後面在增加標籤上用上此class                 
                /*
                if (window.allClass[name]) {//存在id//id式
                    tmp.push(name);
                } else {//不存在
                    continue;
                }
                */
                tmp.push(name);
            } else if (/^\./i.test(name)) {//類名式  
                n = name.split(' ')[0];
                
                if (window.allClass[n]) {//類被使用
                    tmp.push(name);
                } else {//未使用
                    continue;
                }
            } else if (/^#/i.test(name)) {
                n = name.split(' ')[0];
                
                if (window.allClass[n]) {//存在id//id式
                    tmp.push(name);
                } else {//不存在
                    continue;
                }
            } else{//必須是非已知格式//無法預料格式,
                tmp.push(name);
            }
        }
        
        tmp.length && window.css.push(tmp.join(',') + vals);//有用
    }    
    
    function clSpace (str) {//移除樣式內的空格
        str = str.replace(/\s+(?=[\{,;\:\}])/g, '');
        str = str.replace(/([\{,;\:\}])\s+/g, '$1');
        return str;
    }
    
    getObj('outCss').value = window.css.join('\n');
}

</script>
</body>
</html>

-----------------說明--------

只支援一個頁面內是否使用的清理,如果多個檔案可能使用到,需要把所有可能使用到檔案進行手工合併,反正原理是,載入html,取到body下面的所有的子物件的tagname(目前未對此類指定模式進行清理)/id/class樣式名,然後把所有的樣式名進行檢測,如果所有的body子物件都沒使用到,就認為未被使用.將清理.