Как изменить переменную 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

Ответ 1

Оказывается, изменение CSS-переменных возможно с el.style.cssText свойства el.style.setProperty или el.setAttribute или 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);
}

Ответ 2

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

:root {
    --somevar: black;
}

Это будет documentElement.

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

Ответ 3

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

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

Ответ 4

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

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

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

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

Однако получатель вернет значение .setProperty(), только если она была установлена, используя .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>

Ответ 5

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

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>

Ответ 6

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