Следите за единицами измерения
Не забудьте добавить к значениям единицы измерения.
Например, мы должны устанавливать 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 (необязательно)
});