下面範例中的 setStyleRule() 可以用來動態增加 stylesheet 中的項目(selector), applyClass() 則可以用來為物件刪除/附加新的 CSS Style Class (只能是 class).

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="ext_style.js"></script>
<script type="text/javascript">
    function fnInit() {
        setStyleRule("", "#id1", "color:blue;");
    }

    window.addEventListener('load', fnInit);
</script>
</head>
<body>
<h1 id="id1">My Heading 1</h1>
<button type="button" onclick="document.getElementById('id1').style.color = 'red'">
Click Me!</button>
</body>
</html>

載入的 javascript "ext_style.js" 檔案內容如下:

var setStyleRule = function(sheetname, selector, rule) {
    // Is browser too old?
    if (!document.styleSheets) return;

    var stylesheet = (function(sheetName) {
        if (sheetName.length == 0) {
            var cmpFunc = function(i, sheetname) {
                return !document.styleSheets[i].href;
            };
        } else {
            var cmpFunc = function(i, sheetname) {
                return ( document.styleSheets[i].href && 
                         document.styleSheets[i].href.indexOf(sheetname)>=0 );
           }
        }

        for (var i = document.styleSheets.length-1; i>=0; i--)
            if (cmpFunc(i, sheetname))
                return document.styleSheets[i];

        // styleSheets not found
        var style = document.createElement('style');
        style.type = 'text/css';
        document.body.appendChild(style);
        return document.styleSheets[document.styleSheets.length-1];
    })(sheetname);

    // For Browser compatiblity
    if (stylesheet.addRule) {
        stylesheet.addRule(selector, rule);
    } else if (stylesheet.insertRule) {
        stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
    }
}

var applyClass = function(className,element,doRemove) {
    if (typeof element.valueOf() == "string")
        element = document.getElementById(element);

    if (!element) return;
    if (doRemove)
        element.className = element.className.replace(new RegExp("\\b" + className + "\\b","g"));
    else
        element.className = element.className + " " + className;
}

setStyleRule 解說:

  • 第3行: !document.styleSheets 判斷 browser 是否太舊
  • 第5~26行: 把 stylesheet 設定為使用者指定的那一份, 這裡用的是自訂一個不具名函數並立即執行的技巧.
    • 第6~15行: 依傳入的 sheetname 字串長度設定 cmpFunc 函數如何比對 stylesheet 的檔名
    • 第17~19行: 使用上面的 cmpFunc 函數找到檔名為 sheetname 所指定的 stylesheet, 回傳給 stylesheet 物件
    • 第22~25行: 找不到, 新增一份空白 stylesheet, 並回傳給 stylesheet. 注意: 第24行這裡要用 document.body 不能用 document.head 因為 stylesheet 可能出現在 <body></body> 中, 如此才能確保第25行回傳的是這一份空白的 stylesheet.
  • 第29~33行: 判定 browser 相容性並把要新增加的 style 加到 stylesheet

applyClass解說:

  • 第37~38行: 判定 element 如果是字串就用 document.getElementById 取得物件 (所以可以自行取得物件或者傳入物件的 Id)
  • 第40行: 防呆, element 物件不存在
  • 第41~44行: 依參數 doRemove 附加或移除 elementclassName 屬性.
    • 第42行: "\b" 在 RegExp 中的特別意義是 word boundry (開始或結束), 由於放在字串中, '\' 所以必需加上 escape char '\' 以防止被解譯為字元 '\b' (bell).


參考資料:

    文章標籤

    javascript stylesheet CSS

    全站熱搜

    MagicJackTing 發表在 痞客邦 留言(0) 人氣()