До того, как начнёте изучать способы работы со стилями и классами в JavaScript, есть одно важное правило. Надеемся, это достаточно очевидно, но мы все равно должны об этом упомянуть.
Как правило, существует два способа задания стилей для элемента:
- Создать класс в CSS и использовать его:
<div class="...">
- Писать стили непосредственно в атрибуте
style
:<div style="...">
.
JavaScript может менять и классы, и свойство style
.
Классы – всегда предпочтительный вариант по сравнению со style
. Мы должны манипулировать свойством style
только в том случае, если классы «не могут справиться».
Например, использование style
является приемлемым, если мы вычисляем координаты элемента динамически и хотим установить их из JavaScript:
let top = /* сложные расчёты */;
let left = /* сложные расчёты */;
elem.style.left = left; // например, '123px', значение вычисляется во время работы скрипта
elem.style.top = top; // например, '456px'
В других случаях, например, чтобы сделать текст красным, добавить значок фона – описываем это в CSS и добавляем класс (JavaScript может это сделать). Это более гибкое и лёгкое в поддержке решение.
className и classList
Изменение класса является одним из наиболее часто используемых действий в скриптах.
Когда-то давно в JavaScript существовало ограничение: зарезервированное слово типа "class"
не могло быть свойством объекта. Это ограничение сейчас отсутствует, но в то время было невозможно иметь свойство elem.class
.
Поэтому для классов было введено схожее свойство "className"
: elem.className
соответствует атрибуту "class"
.
Например:
<body class="main page">
<script>
alert(document.body.className); // main page
</script>
</body>
Если мы присваиваем что-то elem.className
, то это заменяет всю строку с классами. Иногда это то, что нам нужно, но часто мы хотим добавить/удалить один класс.
Для этого есть другое свойство: elem.classList
.
elem.classList
– это специальный объект с методами для добавления/удаления одного класса.
Например:
<body class="main page">
<script>
// добавление класса
document.body.classList.add('article');
alert(document.body.className); // main page article
</script>
</body>
Так что мы можем работать как со строкой полного класса, используя className
, так и с отдельными классами, используя classList
. Выбираем тот вариант, который нам удобнее.
Методы classList
:
elem.classList.add/remove("class")
– добавить/удалить класс.elem.classList.toggle("class")
– добавить класс, если его нет, иначе удалить.elem.classList.contains("class")
– проверка наличия класса, возвращаетtrue/false
.
Кроме того, classList
является перебираемым, поэтому можно перечислить все классы при помощи for..of
:
<body class="main page">
<script>
for (let name of document.body.classList) {
alert(name); // main, затем page
}
</script>
</body>
Element style
Свойство elem.style
– это объект, который соответствует тому, что написано в атрибуте "style"
. Установка стиля elem.style.width="100px"
работает так же, как наличие в атрибуте style
строки width:100px
.
Для свойства из нескольких слов используется camelCase:
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
Например:
document.body.style.backgroundColor = prompt('background color?', 'green');
Свойства с префиксом
Стили с браузерным префиксом, например, -moz-border-radius
, -webkit-border-radius
преобразуются по тому же принципу: дефис означает заглавную букву.
Например:
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
Сброс стилей
Иногда нам нужно добавить свойство стиля, а потом, позже, убрать его.
Например, чтобы скрыть элемент, мы можем задать elem.style.display = "none"
.
Затем мы можем удалить свойство style.display
, чтобы вернуться к первоначальному состоянию. Вместо delete elem.style.display
мы должны присвоить ему пустую строку: elem.style.display = ""
.
// если мы запустим этот код, <body> "мигнёт"
document.body.style.display = "none"; // скрыть
setTimeout(() => document.body.style.display = "", 1000); // возврат к нормальному состоянию
Если мы установим в style.display
пустую строку, то браузер применит CSS-классы и встроенные стили, как если бы такого свойства style.display
вообще не было.
Полная перезапись style.cssText
Обычно мы используем style.*
для присвоения индивидуальных свойств стиля. Нельзя установить список стилей как, например, div.style="color: red; width: 100px"
, потому что div.style
– это объект, и он доступен только для чтения.
Для задания нескольких стилей в одной строке используется специальное свойство style.cssText
:
<div id="div">Button</div>
<script>
// можем даже устанавливать специальные флаги для стилей, например, "important"
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
</script>
Это свойство редко используется, потому что такое присваивание удаляет все существующие стили: оно не добавляет, а заменяет их. Можно ненароком удалить что-то нужное. Но его можно использовать, к примеру, для новых элементов, когда мы точно знаем, что не удалим существующий стиль.
То же самое можно сделать установкой атрибута: div.setAttribute('style', 'color: red...')
.