Следите за единицами измерения
Не забудьте добавить к значениям единицы измерения.
Например, мы должны устанавливать 10px
, а не просто 10
в свойство elem.style.top
. Иначе это не сработает:
<body>
<script>
// не работает!
document.body.style.margin = 20;
alert(document.body.style.margin); // '' (пустая строка, присваивание игнорируется)
// сейчас добавим единицу измерения (px) - и заработает
document.body.style.margin = '20px';
alert(document.body.style.margin); // 20px
alert(document.body.style.marginTop); // 20px
alert(document.body.style.marginLeft); // 20px
</script>
</body>
Пожалуйста, обратите внимание, браузер «распаковывает» свойство style.margin
в последних строках и выводит style.marginLeft
и style.marginTop
из него.
Вычисленные стили: getComputedStyle
Итак, изменить стиль очень просто. Но как его прочитать?
Например, мы хотим знать размер, отступы, цвет элемента. Как это сделать?
Свойство style
оперирует только значением атрибута "style"
, без учёта CSS-каскада.
Поэтому, используя elem.style
, мы не можем прочитать ничего, что приходит из классов CSS.
Например, здесь style
не может видеть отступы:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
Красный текст
<script>
alert(document.body.style.color); // пусто
alert(document.body.style.marginTop); // пусто
</script>
</body>
…Но что, если нам нужно, скажем, увеличить отступ на 20px
? Для начала нужно его текущее значение получить.
Для этого есть метод: getComputedStyle
.
Синтаксис:
getComputedStyle(element, [pseudo])
elementЭлемент, значения для которого нужно получитьpseudoУказывается, если нужен стиль псевдоэлемента, например ::before
. Пустая строка или отсутствие аргумента означают сам элемент.
Результат вызова – объект со стилями, похожий на elem.style
, но с учётом всех CSS-классов.
Например:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// сейчас мы можем прочитать отступ и цвет
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
Вычисленное (computed) и окончательное (resolved) значения
Есть две концепции в CSS:
- Вычисленное (computed) значение – это то, которое получено после применения всех CSS-правил и CSS-наследования. Например,
height:1em
илиfont-size:125%
. - Окончательное (resolved) значение – непосредственно применяемое к элементу. Значения
1em
или125%
являются относительными. Браузер берёт вычисленное значение и делает все единицы измерения фиксированными и абсолютными, например,height:20px
илиfont-size:16px
. Для геометрических свойств разрешённые значения могут иметь плавающую точку, например,width:50.5px
.
Давным-давно getComputedStyle
был создан для получения вычисленных значений, но оказалось, что окончательные значения гораздо удобнее, и стандарт изменился.
Так что, в настоящее время getComputedStyle
фактически возвращает окончательное значение свойства, для геометрии оно обычно в пикселях.getComputedStyle
требует полное свойство!
Для правильного получения значения нужно указать точное свойство. Например: paddingLeft
, marginTop
, borderTopWidth
. При обращении к сокращённому: padding
, margin
, border
– правильный результат не гарантируется.
Например, если есть свойства paddingLeft/paddingTop
, то что мы получим вызывая getComputedStyle(elem).padding
? Ничего, или, может быть, «сгенерированное» значение из известных внутренних отступов? Стандарта для этого нет.
Есть и другие несоответствия. Например, некоторые браузеры (Chrome) отображают 10px
в документе ниже, а некоторые (Firefox) – нет:
<style>
body {
margin: 10px;
}
</style>
<script>
let style = getComputedStyle(document.body);
alert(style.margin); // пустая строка в Firefox
</script>
Стили, применяемые к посещённым :visited
ссылкам, скрываются!
Посещённые ссылки могут быть окрашены с помощью псевдокласса :visited
.
Но getComputedStyle
не даёт доступ к этой информации, чтобы произвольная страница не могла определить, посещал ли пользователь ту или иную ссылку, проверив стили.
JavaScript не видит стили, применяемые с помощью :visited
. Кроме того, в CSS есть ограничение, которое запрещает в целях безопасности применять к :visited
CSS-стили, изменяющие геометрию элемента. Это гарантирует, что нет обходного пути для «злой» страницы проверить, была ли ссылка посещена и, следовательно, нарушить конфиденциальность.
Итого
Для управления классами существуют два DOM-свойства:
className
– строковое значение, удобно для управления всем набором классов.classList
– объект с методамиadd/remove/toggle/contains
, удобно для управления отдельными классами.
Чтобы изменить стили:
- Свойство
style
является объектом со стилями в формате camelCase. Чтение и запись в него работают так же, как изменение соответствующих свойств в атрибуте"style"
. Чтобы узнать, как добавить в негоimportant
и делать некоторые другие редкие вещи – смотрите документацию. - Свойство
style.cssText
соответствует всему атрибуту"style"
, полной строке стилей.
Для чтения окончательных стилей (с учётом всех классов, после применения CSS и вычисления окончательных значений) используется:
- Метод
getComputedStyle(elem, [pseudo])
возвращает объект, похожий по формату наstyle
. Только для чтения.
Практика
Задачи
Создать уведомление
важность: 5
Напишите функцию showNotification(options)
, которая создаёт уведомление: <div class="notification">
с заданным содержимым. Уведомление должно автоматически исчезнуть через 1,5 секунды.
Пример объекта options
:
// показывает элемент с текстом "Hello" рядом с правой верхней частью окна.
showNotification({
top: 10, // 10px от верхней границы окна (по умолчанию 0px)
right: 10, // 10px от правого края окна (по умолчанию 0px)
html: "Hello!", // HTML-уведомление
className: "welcome" // дополнительный класс для div (необязательно)
});