Как динамически создать CSS-класс в JavaScript и применить? - PullRequest
261 голосов
/ 12 ноября 2009

Мне нужно динамически создать класс таблицы стилей CSS в JavaScript и назначить его некоторым элементам HTML, таким как - div, table, span, tr и т. Д., А также некоторым элементам управления, таким как asp: Textbox, Dropdownlist и datalist.

Возможно ли это?

Было бы неплохо с образцом.

Ответы [ 14 ]

1 голос
/ 10 июля 2015

Просматривал ответы, и самое очевидное и прямолинейное отсутствует: используйте document.write(), чтобы написать кусок CSS, который вам нужен.

Вот пример (посмотрите его на codepen: http://codepen.io/ssh33/pen/zGjWga):

<style>
   @import url(http://fonts.googleapis.com/css?family=Open+Sans:800);
   .d, body{ font: 3vw 'Open Sans'; padding-top: 1em; }
   .d {
       text-align: center; background: #aaf;
       margin: auto; color: #fff; overflow: hidden; 
       width: 12em; height: 5em;
   }
</style>

<script>
   function w(s){document.write(s)}
   w("<style>.long-shadow { text-shadow: ");
   for(var i=0; i<449; i++) {
      if(i!= 0) w(","); w(i+"px "+i+"px #444");
   }
   w(";}</style>");
</script> 

<div class="d">
    <div class="long-shadow">Long Shadow<br> Short Code</div>
</div>
1 голос
/ 21 марта 2014

Использование Google Closure:

Вы можете просто использовать модуль ccsom:

goog.require('goog.cssom');
var css_node = goog.cssom.addCssText('.cssClass { color: #F00; }');

Код javascript пытается быть кроссбраузерным при размещении узла css в заголовке документа.

0 голосов
/ 12 февраля 2019

Я просматривал некоторые ответы здесь, и я не смог найти ничего, что автоматически добавляет новую таблицу стилей, если ее нет, и если нет, то просто изменяет существующую, которая уже содержит необходимый стиль, поэтому я сделал новая функция (должна работать во всех браузерах, хотя и не тестировалась, использует addRule и, кроме того, только базовый собственный JavaScript, дайте мне знать, если он работает):

function myCSS(data) {
    var head = document.head || document.getElementsByTagName("head")[0];
    if(head) {
        if(data && data.constructor == Object) {
            for(var k in data) {
                var selector = k;
                var rules = data[k];

                var allSheets = document.styleSheets;
                var cur = null;

                var indexOfPossibleRule = null,
                    indexOfSheet = null;
                for(var i = 0; i < allSheets.length; i++) {
                    indexOfPossibleRule = findIndexOfObjPropInArray("selectorText",selector,allSheets[i].cssRules);
                    if(indexOfPossibleRule != null) {
                        indexOfSheet = i;
                        break;
                    }
                }

                var ruleToEdit = null;
                if(indexOfSheet != null) {

                    ruleToEdit = allSheets[indexOfSheet].cssRules[indexOfPossibleRule];

                } else {
                    cur = document.createElement("style");
                    cur.type =  "text/css";
                    head.appendChild(cur);
                    cur.sheet.addRule(selector,"");
                    ruleToEdit = cur.sheet.cssRules[0];
                    console.log("NOPE, but here's a new one:", cur);
                }
                applyCustomCSSruleListToExistingCSSruleList(rules, ruleToEdit, (err) => {
                    if(err) {
                        console.log(err);
                    } else {
                        console.log("successfully added ", rules, " to ", ruleToEdit);
                    }
                });
            }
        } else {
            console.log("provide one paramter as an object containing the cssStyles, like: {\"#myID\":{position:\"absolute\"}, \".myClass\":{background:\"red\"}}, etc...");
        }
    } else {
        console.log("run this after the page loads");
    }

};  

, затем просто добавьте эти 2 вспомогательные функции либо внутри вышеуказанной функции, либо в любом другом месте:

function applyCustomCSSruleListToExistingCSSruleList(customRuleList, existingRuleList, cb) {
    var err = null;
    console.log("trying to apply ", customRuleList, " to ", existingRuleList);
    if(customRuleList && customRuleList.constructor == Object && existingRuleList && existingRuleList.constructor == CSSStyleRule) {
        for(var k in customRuleList) {
            existingRuleList["style"][k] = customRuleList[k];
        }

    } else {
        err = ("provide first argument as an object containing the selectors for the keys, and the second argument is the CSSRuleList to modify");
    }
    if(cb) {
        cb(err);
    }
}

function findIndexOfObjPropInArray(objPropKey, objPropValue, arr) {
    var index = null;
    for(var i = 0; i < arr.length; i++) {
        if(arr[i][objPropKey] == objPropValue) {
            index = i;
            break;
        }
    }
    return index;
}

(обратите внимание, что в обоих из них я использую цикл for вместо .filter, поскольку классы стилей / правил CSS имеют только свойство length и не имеют метода .filter.)

Тогда, чтобы назвать это:

myCSS({
    "#coby": {
        position:"absolute",
        color:"blue"
    },
    ".myError": {
        padding:"4px",
        background:"salmon"
    }
})

Дайте мне знать, работает ли он в вашем браузере или выдает ошибку.

0 голосов
/ 07 августа 2015

В пользу поисковиков; если вы используете jQuery, вы можете сделать следующее:

var currentOverride = $('#customoverridestyles');

if (currentOverride) {
 currentOverride.remove();
}

$('body').append("<style id=\"customoverridestyles\">body{background-color:pink;}</style>");

Очевидно, что вы можете изменить внутренний CSS так, как вам хочется.

Цените, что некоторые люди предпочитают чистый JavaScript, но он работает и достаточно надежен для динамического написания / перезаписи стилей.

...