對我來說,Javascript在處理CSS上一直有一個小困擾...

一般在習慣上,為了方便開發人員修改,多半會將Style設定獨立放在.css檔案裡,應用者可視需要覆寫或修改之。但有蠻多時候,應用者根本不打算更動CSS內容,只想直接沿用預設CSS設定,但部署時還是少不了要Copy相對應的.css檔案,網頁也必須多加上<style src="/img/loading.svg" data-src="...">宣告。

我總覺得,最理想的方式是將預設css與js融和在一個檔案裡。當開發者想自行定義CSS樣式,可將其寫在.css中加以引用,或在HTML中以<style>逕行宣告;若只想用預設內容,則只需參照.js就大功告成。

今天遇到類似需求,索性寫了幾個小函數,試著實現上述想法。

我的設計概念是這樣的: 先透過document.styleSheets.cssRules比對某個CSS Selector(例如: div.cCountryPicker),若已被定義過,表示網頁已透過參照.css檔或直接宣告<style type="text/css">方式定義了div.cCounterPicker,此時就不需加入預設的div.cCountryPicker樣式規則;反之,若沒有定義該規則,則透過$("head").append("<style type=\"text/css\">....")的方式加入Style宣告。

程式碼如下:
(PS: 我規劃用jQuery.Darkthread.*蒐集我陸續開發出來的工具函數,最前面的$.extend用來將多個.js中宣告的jQuery.Darkthread.*函數彙整在一起)

/*
** Darkthread's Tools for jQuery ver 1.0 **
by Jeffrey, 2010-02-25, http://blog.darkthread.net
=======================================================
checkStyle: to check if specific style selector is defined
addStyles: add <style type="text/css"> dynamically
addDefaultStyles: if specific style selector isn't defined, add style setting
 
*/
jQuery.extend(jQuery, { Darkthread: {} });
jQuery.extend(jQuery.Darkthread, {
    tools: {
        //ruleSelector sample: a:hover, .myClass, #someId
        checkStyle:
        function(ruleSelector) {
            //REF: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml
            var cssCol = document.styleSheets;
            ruleSelector = ruleSelector.toLowerCase();
            for (var i = 0; i < cssCol.length; i++) {
                var rules = cssCol[i].cssRules || cssCol[i].rules;
                for (j = 0; j < rules.length; j++)
                    if (rules[j].selectorText.toLowerCase() == ruleSelector)
                    return true;
            }
            return false;
        },
        /*styleDictionary sample:
        { 
        "a:hover": { "background-color": "red", "color":"yellow" },
        "#dvTest": { "border", "solid blue 1px" }
        }
        Note: it's for <style> declaration, not for jQuery.css, so don't use 
        backgourndColor instead of "background-color"
        */
        addStyles:
        function(styleDictionary) {
            var sb = [];
            for (var selector in styleDictionary) {
                sb.push(selector + " {");
                var props = styleDictionary[selector];
                for (var p in props) {
                    sb.push(p + ":" + props[p] + ";");
                }
                sb.push("}");
            }
            $("head").append("<style type=\"text/css\">\n" +
                sb.join("\n") + "\n</style>");
        },
        addDefaultStyles:
        function(ruleSelector, styleDictionary) {
            if (!$.Darkthread.tools.checkStyle(ruleSelector))
                $.Darkthread.tools.addStyles(styleDictionary);
        }
    }
});

應用方式挺簡單的,將以下的程式寫進.js,等於將預設的.css一起藏進.js裡,就不必再多搞出一個預設用途的.css檔案囉!

    $.Darkthread.tools.addDefaultStyles(".dttl_BookingBlock", {
        ".dttl_BookingBlock": {
            float: "left", position: "absolute",
            margin: "0px", padding: "0px", height: "100%",
            "font-size": "9pt", "background-color": "#dddddd",
            "border-left": "solid #444444 1px",
            "border-right": "solid #444444 1px"
        },
        ".ddtl_Timeline": { border: "solid red 1px" }
    });

(以上的程式碼,會在網頁本身沒有宣告.dttl_BookingBlock且所有參照的.css中也沒有該宣告時,加入.dttl_BookingBlock及.dttl_Timeline兩條CSS規則,賦與預設Style設定。)


Comments

Be the first to post a comment

Post a comment