Какая JavaScript-инфраструктура может искать правила таблицы стилей CSS и редактировать их свойства? - PullRequest
15 голосов
/ 13 июля 2011

Вопрос

Какая платформа JavaScript (prototype, script.aculo.us, Mootools, MochiKit ...) имеет достойное редактирование правил CSS поддержка?

Речь идет об изменении правила стиля.Я хочу иметь динамические классы CSS , которые меняются.Пример:

<style>
#answer, .reveal { display: none; color: blue; }
#answer { /* additional stuff */ }
</style>

Теперь с помощью JavaScript я хочу изменить правило, в котором есть «display: none».- Я убежден, что иногда это правильный путь;Я не ищу альтернативы, когда это не правильный способ сделать.

Какая инфраструктура облегчает следующее:

  1. выбирает правило из всех правил (например, "#answer, .reveal")
  2. какое значение имеетвыбранные правила имеют для «отображения»?
  3. удалить свойство «отображения» из правила (й)

(2 и 3. легко с помощью одного DOM,пока я получаю дескриптор правила CSS из фреймворка)

Недостаточно хорошие фреймворки: например,

Таблица стилей YUI может искать правила только на одном листевремя (ограничено, но достаточно для меня), но оно не может отображать, редактировать или извлекать правила мультиселектора, как в моем первом примере (слишком ограничено на мой вкус).

У YUI также нет способа получить индивидуальныйсвойства (базовый DOM может, но вы не можете получить эту структуру через YUI).Вы могли бы удалить только свойство display, однако, если вы овладели правилом средствами YUI.

В Dojo есть плохо документированные и неполные данные в dojox.html.styles

Ext JS имеет Ext.util.CSS.Я проверил код и обнаружил ошибку в getRule () ... В остальном он довольно неаккуратен из-за выбора селектора (плохое влияние IE), что делает его плохим для правил мультиселектора.Он также не может удалять свойства через API, но может дать вам CSSRule, чтобы вы могли сделать это самостоятельно.- Ходьба по дереву CSS настолько примитивна, насколько это возможно: не спускаться по правилам мультимедиа или импортам.

PD:

$ ('. Предоставить'). Css (... что угодно...) это не ответ, потому что он вообще не касается правил CSS (вместо этого он касается атрибутов CSS некоторых элементов)!

Ответы [ 4 ]

3 голосов
/ 15 июля 2011

Нет, но, пожалуйста, докажите, что я не прав ...

A Приличная реализация должна сначала обсудить / документировать следующее:

  • как это происходитдерево CSS (включая @imports и @media)
  • как можно настроить обход (какие @media и какие листы учитываются)
  • способ обработки / обхода ограничений междоменного доступа
  • , поскольку у CSS нет идентификаторов для самих правил: только селектор может выступать в качестве приличных идентификаторов правил
    • как IE8 и несколько разделенных мультиселекторов, насколько разумна структура для обработки этого?
    • IE9 хуже (см. quirksmode.org )
  • , так как одним селектором может быть выбрано несколько правил, как они упорядочены?
  • как найти ответственное правило из набора правил, зная свойство, которое мы хотим отредактировать?

До тех пор, пока фреймворки не догонят, рассмотрим:

  • получить узел style / link, в котором используется искомое правило
  • node.sheet, чтобы перейти непосредственно к CSSStyleSheet
  • проверить quirksmode.org на наличие причуд и f ... IE
  • выполнить цикл по правилам, чтобы найти ваши правила через известные селектор
  • DOM CSSStyleRule дает вам всю необходимую силу над любым правилом стиля
1 голос
/ 14 июля 2011

Как вы заметили, в YUI есть утилита StyleSheet http://developer.yahoo.com/yui/3/stylesheet/

Пример:

var sheet = new Y.StyleSheet(styleNode);
sheet.set('.hover, .foo:hover', {
    background: 'red',
    color: '#fff'
});

Она также поддерживает создание таблиц стилей с нуля, передавая конструктору строку правил CSS.

Обратите внимание, что одна и та же политика источника предотвращает доступ к правилам узлов ссылок удаленного источника.

Она пока не поддерживает доступ к правилам в виде дерева объектов или доступ к определенным свойствам правил.Тем не менее, он поддерживает удаление правил или свойств правил.На сегодняшний день лучшее, что вы можете сделать для работы с правилами, поскольку объекты будут выглядеть примерно так:

var style = sheet.getCssText('.foo'),
    tmp = document.createElement('div');

tmp.style.cssText = sheet.getCssText('.foo');
if (tmp.style.display) { // does the rule include a setting for display
    ...
}

Поскольку возмущение таблицами стилей во время выполнения довольно редко является правильным решением, утилита не имеет большого количества разработчиков.фокус для добавления функций.Просьба о новых функциях приветствуется.

0 голосов
/ 12 марта 2018

Вопрос Роберт Симер объяснил:

Речь идет об изменении правила стиля. Я хочу иметь динамические классы CSS, которые меняются.

Я хотел бы дать ответ, который лучше определяет вопрос для читателей, которые ищут подобную вещь, и для авторов, которые перепутали проблему с обновлением стиля элемента.

Говядина

Я думаю, что первая часть говядины заключается в том, что браузеры разрешают манипулировать существующими таблицами стилей , как это подразумевается в этом комментарии и анализируются в этот ответ . Например, следующая строка изменяет значение padding-top с 20px до 300px для третьего правила во второй таблице стилей документа:

document.styleSheets[1].cssRules[2].style.paddingTop = '300px'

... дано index.html:

<html>
<head>
  <link type="text/css" href="foo.css"
  <link type="text/css" href="style.css">
<head>
<body><h1>Bar</h1></body>
</html>

... и style.css:

html, body { padding: 0; margin: 0 }
body { color: black; }
h1 { color: gray; padding-top: 20px; }

Вторая часть говядины - это как найти правила, которые соответствуют критерию. Обе части имеют проблемы с совместимостью со старыми браузерами, как обсуждалось в ответе . Если мы забудем о проблемах совместимости и сконцентрируемся на том, как примерно должна работать такая структура, вот моя минимальная реализация в vanilla JavaScript.

микрокаркас

function forEachCSSRule (iteratee) {
  var i, j, crs
  for (i = 0; i < document.styleSheets.length; i += 1) {
    crs = document.styleSheets[i].cssRules
    for (j = 0; j < crs.lenght; j += 1) {
      iteratee(crs[j])
    }
  }
}

function getCSSRulesBySelector (selectorString) {
  var matched = []
  forEachCSSRule(function (cr) {
    if (cr.selectorText.includes(selectorString)) {
      matched.push(cr)
    }
  })
  return matched
}

function getCSSRulesByStyle (styleString) {
  var matched = []
  forEachCSSRule(function (cr) {
    if (cr.cssText.includes(styleString)) {
      matched.push(cr)
    }
  })
  return matched
}

С такой структурой вы можете, например:

var rules = getCSSRulesByStyle('display: none')
rules.forEach(function (rule) {
  rule.style.display = 'block'
})

... что и было задано в оригинальном вопросе.

0 голосов
/ 13 ноября 2015

Существуют библиотеки, такие как postCSS , которые позволяют использовать модульную экосистему плагинов для программного изменения стилей CSS.

...