Получение содержимого класса CSS из нескольких таблиц стилей с помощью JS

#javascript #css

#javascript #css

Вопрос:

У меня есть библиотека JS, использующая canvas, которая должна получать свои цвета из классов CSS. Классы, используемые библиотекой, предопределены, но какая таблица стилей (из, возможно, многих) — нет.

С таким классом, как этот:

 .a_preset_class {
    margin: 10pt;
    color: rgba(216,34,21,0.5);
}
  

Я хотел бы иметь возможность написать что-то вроде этого:

context.strokeStyle = getClassColor("a_preset_class");

и должны context.strokeStyle быть установлены в "rgba(216,34,21,0.5);"

Очевидный способ — пройти document.styleSheets , но я надеюсь, что есть менее радикальный способ, о котором я не знаю.

Ответ №1:

Если вы можете использовать Dojo на своем сайте, вы можете использовать dojox.data .CssRuleStore для создания хранилища всех ваших правил CSS с возможностью поиска. Затем вы используете стандартный метод fetch() для поиска в хранилище, используя свойство правила стиля «selector» в качестве поискового запроса. Например.,

 ruleStore = dojox.data.CssRuleStore(); // make it a global if it's not part of a widget
                                       // so that it's accessible by the other methods
                                       // below when calling ruleStore.getValue()
var rulesFound = [];

// When querying the store, you can either do an exact match search such as ".myClass",
// or do a wildcard-based search such as ".myClass*" (find all rules that start with
// ".myClass", "*.myClass*" (all rules containing ".myClass" somewhere in the selector),
// "?someValue" (any rules that have an arbitrary first character, followed by
// "someRule"), etc.
var queryObj = {"selector": ".a_preset_class"};

var checkEmpty = function(count, request) {
    if (count < 1)
        // do your empty response logic here
};

var processRule = function(item, request) {
    rulesFound.push(ruleStore.getValue(item, "style"); // Add the item's CSSStyleDeclaration object with all assigned values to the results array
};

ruleStore.fetch({query: queryObj, onBegin: checkEmpty, onItem: processRule});
  

Используя этот код в качестве отправной точки, вы можете создать функцию, которая принимает желаемый поисковый запрос в качестве своего параметра, передает его в запрос, а затем возвращает массив найденных правил CSS. Затем вы можете просто выполнить итерацию массива ответов после вызова функции и внести любые необходимые изменения.

Ответ №2:

 var who= document.createElement('span');
who.className="a_preset_class";
var css= document.defaultView.getComputedStyle(who,'').getPropertyValue('background-color');
  

Комментарии:

1. Это быстрее, чем обход, но вы не можете сказать, отсутствует ли класс, поскольку к нему будет применен стиль по умолчанию для элемента. Кроме того, вам нужно добавить элемент на страницу, чтобы применить класс.

Ответ №3:

Вот функция, которую вы можете использовать повторно…

 function testrules(findrule)
{
 var myrules = document.styleSheets[0].cssRules;

 for (var i=0; i<myrules.length.length; i  )
 {
  if (myrules[i].selectorText==findrule) {alert('document.styleSheets[0].cssRules[' i '] = ' myrules[i].cssText); break;}
 }
}
  

Вызовите функцию как so…

 <div><a href="javascript:testrules('a:hover');">what is a:hover?</a></div>
  

С некоторой модификацией вы можете заставить его возвращать значение или ‘0’, если не было выполнено ни одно правило сопоставления. Вы также можете легко выполнить итерацию по нескольким таблицам стилей со вторым циклом for .

Комментарии:

1. Это то, что я подразумеваю под обходом document.styleSheets ; это метод, которого я надеюсь избежать. Кроме того, я не могу полагаться на классы, находящиеся внутри document.styleSheets[0] .