it-swarm.com.ru

Как мне отредактировать переменную CSS с помощью JS?

У меня есть эти CSS-переменные для управления цветами моего проекта, чтобы я мог делать темы. 

html {
    --main-background-image: url(../images/starsBackground.jpg);
    --main-text-color: #4CAF50;
    --main-background-color: rgba(0,0,0,.25);
    --beta-background-color: rgba(0,0,0,.85);
}

Однако, независимо от того, как я пытаюсь изменить атрибут (две прокомментированные строки, пробованные отдельно), самое близкое, что я получаю, это возвращение недопустимого атрибута.

function loadTheme() {
    var htmlTag = document.getElementsByTagName("html");
    var yourSelect = document.getElementById( "themeSelect" );
    var selectedTheme = ( yourSelect.options[ yourSelect.selectedIndex ].value );
    // htmlTag[0].setAttribute('--main-text-color', '#FFCF40');
    // $("html").css("--main-text-color","#FFCF40");
}

the error message

24
David Richards

Оказывается, изменение CSS-переменных возможно с помощью свойства el.style.cssText или методов el.style.setProperty или el.setAttribute. В вашем коде фрагменты el.setAttribute неправильно используются, что вызывает ошибку, с которой вы столкнулись. Вот правильный путь:

var html = document.getElementsByTagName('html')[0];
html.style.cssText = "--main-background-color: red";

или же

var html = document.getElementsByTagName('html')[0];
html.style.setProperty("--main-background-color", "green");

или же

var html = document.getElementsByTagName('html')[0];
html.setAttribute("style", "--main-background-color: green");

Демо

Следующая демонстрация определяет цвет фона с помощью переменной CSS, а затем изменяет его с помощью фрагмента JS через 2 секунды после загрузки. 

window.onload = function() {
  setTimeout(function() {
    var html = document.getElementsByTagName('html')[0];
    html.style.cssText = "--main-background-color: red";
  }, 2000);
};
html {
    --main-background-image: url(../images/starsBackground.jpg);
    --main-text-color: #4CAF50;
    --main-background-color: rgba(0,0,0,.25);
    --beta-background-color: rgba(0,0,0,.85);
}

body {
  background-color: var(--main-background-color);
}

Это будет работать только в браузерах, поддерживающих переменные CSS. 

19
Brett DeWoody

Если вы используете :root:

:root {
    --somevar: black;
}

Это будет документЭлемент.

document.documentElement.style.setProperty('--somevar', 'green');
14
Blauhirn

Вы можете просто использовать стандартный способ установки произвольных свойств CSS: setProperty

document.body.style.setProperty('--background-color', 'blue');
body {
  --background-color: red;
  background-color: var(--background-color);
}

11
Oriol

Нативное решение

Стандартными методами для получения/установки переменных CSS3 являются .setProperty() и .getPropertyValue().

Если ваши переменные являются глобальными (объявлены в :root), вы можете использовать следующее для получения и установки их значений.

// setter
document.documentElement.style.setProperty('--myVariable', 'blue');
// getter
document.documentElement.style.getPropertyValue('--myVariable');

Однако получатель вернет значение переменной, только если она была установлена, используя .setProperty(). Если это было установлено через объявление CSS, вернет undefined. Проверьте это в этом примере:

let c = document.documentElement.style.getPropertyValue('--myVariable');
alert('The value of --myVariable is : ' + (c?c:'undefined'));
:root{ --myVariable : red; }
div{ background-color: var(--myVariable); }
  <div>Red background set by --myVariable</div>

Чтобы избежать такого неожиданного поведения, вы должны использовать метод getComputedStyle(), прежде чем вызывать .getPropertyValue(). Тогда получатель будет выглядеть так:

getComputedStyle(document.documentElement,null).getPropertyValue('--myVariable');

На мой взгляд, доступ к переменным CSS должен быть более простым, быстрым, интуитивно понятным и естественным ...


Мой личный подход

Я реализовал CSSGlobalVariablesa крошечный (<3kb) помощник javascript, который автоматически обнаруживает и упаковывает в объект все активные глобальные переменные CSS в документе, для облегчения доступа и манипулирования.

// set a new value to --myVariable
cssVar.myVariable = 'red';
// get the value of --myVariable
console.log( cssVar.myVariable );

Любое изменение, примененное к свойствам объекта, автоматически переводится в переменные CSS. 

Доступно в: https://github.com/colxi/css-global-variables

7
colxi

Вы можете добавить что-то вроде ниже (без использования переменных класса)

function loadTheme() {
  var htmlTag = document.getElementById("myDiv");
  var yourSelect = document.getElementById("themeSelect");
  var selectedTheme = (yourSelect.options[yourSelect.selectedIndex].value);
  console.log("selected theme: " + selectedTheme);

  // reset class names
  htmlTag.className = '';
  // add selected theme
  htmlTag.className = 'theme' + selectedTheme;
}
.theme1 {
  color: blue;
}
.theme2 {
  color: red;
}
<div id="myDiv">
  test
</div>
<select id="themeSelect" onChange="loadTheme()">
  <option value="1">Theme 1</option>
  <option value="2">Theme 2</option>
</select>

1
ochi

Вероятно, будет проще определить классы в вашем CSS, которые содержат различные стили темы (.theme1 {...}, .theme2 {...} и т.д.), А затем изменить класс с помощью JS на основе выбранного значения.

0
johnniebenson