星期三, 7月 28, 2010

動態新增、修改、刪除 CSS Rule

需求:有一個動態網頁,每個物件都是動態載入,每一種物件都允許自訂顏色,因此我用物件的type id做為CSS的名稱,設定後立即生效。


利用jQuery搭配AJAX確實很方便,但是jQuery的selector只針對目前存在的DOM物件有效,雖然有神奇的 .live ,很可惜只對Event有效果,對於CSS並沒有類似的API。
後來找到JavaScript Kit上的Changing external style sheets using the DOM,照著這三篇的做法就可以動態新增、修改、刪除 CSS Rule,不需要在檔案定義。黑暗執行緒李明儒大師寫了篇動態加入預設Style設定,將新增預設CSS Rule擴充至jQuery。我自己先簡單地把修改的部份直接寫成先檢查存不存在,若存在就刪除再新增,這樣很不好的暴力寫法XD 程式碼如下:

function changeCSSRule(classToSet, rulesToSet) {
    for (var k = 0; k < document.styleSheets.length; k++) {
        var mysheet = document.styleSheets[k];
        var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
        mysheet.crossdelete = mysheet.deleteRule ? mysheet.deleteRule : mysheet.removeRule;
        if(myrules != null) //若不加此檢查,V8 engine 會有錯誤
        {
           for (var j = 0; j < myrules.length; j++) {
               if (myrules[j].selectorText == classToSet) {
                   mysheet.crossdelete(j)
                   j-- //decrement i by 1, since deleting a rule collapses the array by 1
               }
           }
        }
        if (mysheet.insertRule) {
            mysheet.insertRule(classToSet + "{" + rulesToSet + "}", 0);
        }
        else if (mysheet.addRule) {
            mysheet.addRule(classToSet, rulesToSet);
        }
    }
}
比較弔詭的情形是若只改document.styleSheets[0]的話是無效的,所以我昨天照著這裏的範例試並沒有成功,各位朋友可自行測試。

MSDN上addRule有許多限制,在IE7及以下並不支援selector或是"b, a"這種同時設定兩個以上class的寫法,但支援"div a"之類的寫法,請注意。

沒有留言: