Эта глава — о свойствах стиля, получении о них информации и изменении при помощи JavaScript.
Перед прочтением, убедитесь, что хорошо знакомы с CSS Box Model. Вы должны хорошо понимать, что такое padding, margin, border.
className
Свойство className соответствует HTML-атрибуту class.
Пример его использования (добавление класса):
<body class="class1 class2"> <script> alert(document.body.className); *!* document.body.className += ' class3'; */!* </script> </body>
Так как классы перечислены через пробел, то для удаления можно производить строковые операции, например с использованием регулярных выражений, а можно просто разбить строку по пробелу.
Все JavaScript-фреймворки имеют встроенные функции для добавления, удаления и проверки класса.
Можно написать такую функцию и самостоятельно, например:
function addClass(el, cls) {
var c = el.className.split(' ');
for (var i=0; i<c.length; i++) {
if (c[i] == cls) return;
}
c.push(cls);
el.className = c.join(' ');
}
function removeClass(el, cls) {
var c = el.className.split(' ');
for (var i=0; i<c.length; i++) {
if (c[i] == cls) c.splice(i--, 1);
}
el.className = c.join(' ');
}
function hasClass(el, cls) {
for (var c = el.className.split(' '),i=c.length-1; i>=0; i--) {
if (c[i] == cls) return true;
}
return false;
}
Сделайте желтыми ссылки внешние ссылки. Все относительные ссылки и абсолютные с доменом javascript.ru считаются внутренними. Желтый цвет должен обеспечиваться установкой класса external.
<style>
.external { background-color: yellow }
</style>
<ul>
<li><a href="http://google.com">http://google.com</a></li>
<li><a href="/tutorial">/tutorial.html</a></li>
<li><a href="ftp://ftp.com/my.zip">ftp://ftp.com/my.zip</a></li>
<li><a href="http://nodejs.org">http://nodejs.org</a></li>
<li><a href="http://javascript.ru/test">http://javascript.ru/test</a></li>
<li><a href="ftp://javascript.ru/file">ftp://javascript.ru/file</a></li>
</ul>
Результат:
Сначала можно найти ссылки, например, при помощи document.getElementsByTagName('a').
Как вы думаете, для проверки адреса нужно получить использовать свойство href, или атрибут getAttribute('href') ? В чем будет различие?
Правила опередения:
- Cсылки без протокола
://являются заведомо внутренними. - Там, где протокол есть — нужно создать новую строку из того, что идёт после
://(indexOf + slice) и проверить начало на совпадение сjavascript.ru.
Код решения: tutorial/browser/dom/markLinks.html
classList
Свойство classList поддерживается во всех современных браузерах, но не в IE<10. Поэтому, скорее всего, эта секция будет для вас ознакомительной, на будущее ![]()
Оно предоставляет удобный интерфейс для работы с классами элемента:
elem.classList.contains(cls)— проверяет, есть ли у элемента классclselem.classList.add/remove(cls)— добавляют/удаляют классclselem.classList.toggle(cls)— добавляет классcls, если его нет, а если есть — удаляет.
Вы можете пользоваться им, если не нужно поддерживать IE<10.
style
Свойство style дает доступ к стилю элемента. Это свойство можно как читать, так и править.
С помощью него можно изменять большинство CSS-свойств, например element.style.width='100px' работает так, как будто у элемента есть атрибут style="width:100px".
Так же, как и в CSS, вам нужно указывать единицы измерения: ‘px’, ‘pt’, ‘%’ или ‘em’.
Для свойств, названия которых состоят из нескольких слов, используется вотТакаяЗапись:
background-color => backgroundColor z-index => zIndex border-left-width => borderLeftWidth
Значение style всегда перезаписывает CSS-свойства, поэтому вы можете внести изменения, а затем вернуть все как было, присвоив style пустую строку: elem.style.width=''.
Пример использования style:
// введите пустое значение, чтобы сбросить цвет
document.body.style.backgroundColor = prompt('background color?', 'green')
Специфические свойства браузеров, типа -moz-border-radius, -webkit-border-radius, записываются следующим способом:
button.style.MozBorderRadius = '5px' button.style.WebkitBorderRadius = '5px'
Конечно, лучше хранить их в отдельных классах, а применять к элементу путем добавления/удаления elem.className.
style.cssText
Свойство style.cssText позволяет читать/записывать целую декларацию:
<div>Button</div>
<script>
var div = document.body.children[0];
div.style.cssText="*!*color: red !important;*/!* \
background-color: yellow; \
width: 100px; \
text-align: center; \
*!*blabla: 5; \*/!*
";
alert(div.style.cssText);
</script>
Браузер парсит cssText и применяет известные ему свойства. Нет никаких ограничений на запись несуществующих свойств, типа blabla - большинство браузеров его просто проигнорируют.
Например, свойство blabla не отобразится в Firefox.
style.cssText - это единственный способ добавить !important.
При установке style.cssText все существующие свойства style перезаписываются. Поэтому, по возможности, используют более конкретные подсвойства style: style.color, style.width и т.п.
Получение информации о style
Зачастую перед нами встают задачи, для решения которых нужно узнать размер элемента, отступ и т.п.
Свойство style позволяет читать эту информацию, но лишь ту, которая доступна напрямую из свойства/атрибута "style":
<body style="color:red">
Красный текст
<script>
alert(document.body.style.color); // red
</script>
</body>
Если же стиль получен из CSS, особенно когда задано составное свойство (margin вместо margin-top), то style «не знает» об этом.
Попытка получить marginTop в этом примере, будет неудачной:
<style>
body { margin: 10px }
</style>
<body>
<script>
alert(document.body.style.marginTop)
</script>
</body>
..А вот если сначала присвоить свойство через style, а затем прочесть, то все сработает отлично:
<body>
<script>
document.body.style.margin = '20px';
alert(document.body.style.marginTop); // 20px!
</script>
</body>
Обратите внимание на то, как браузер «распаковал» свойство style.margin, предоставив для чтения style.marginTop. Тоже самое произойдет и для border, background и т.д.
Свойство в стиле может быть показано не в точности, как его назначали, а как его воспринял браузер.
В примере ниже, color будет показан в виде rgb(...) в Firefox:
<body style="color:#abc">
<script>
alert(document.body.style.color); // rgb(170, 187, 204)
</script>
</body>
В следующей задаче охватываются наиболее используемые свойства.
Возьмите документ, расположенный по адресу tutorial/browser/dom/roundedButton/source.html и создайте ссылку <A> с заданным стилем, используя JavaScript.
В примере ниже кнопка создана при помощи HTML/CSS. В решении кнопка должна создаваться, настраиваться и добавляться в документ при помощи только JavaScript, без тегов <style> и <a>.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
.button {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
border: 2px groove green;
display: block;
height: 30px;
line-height: 30px;
width: 100px;
text-decoration: none;
text-align: center;
color: red;
font-weight: bold;
}
</style>
</head>
<body>
<a class="button" href="/">Нажми меня</a>
</body>
</html>
Показать в отдельном окне
Проверьте себя: вспомните, что означает каждое свойство, опишите зачем оно здесь.
Есть два варианта.
- Можно использовать свойство
elem.style.cssTextи присвоить стиль в текстовом виде. При этом все присвоенные ранее свойстваelem.styleбудут удалены. - Можно назначить подсвойства
elem.styleодно за другим. Это более безопасно, т.к. меняет только явно присваемые свойства.
Мы выберем второй пусть в решении: tutorial/browser/dom/roundedButton/solution.html.
Описание CSS-свойств:
.button {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
border: 2px groove green;
display: block;
height: 30px;
line-height: 30px;
width: 100px;
text-decoration: none;
text-align: center;
color: red;
font-weight: bold;
}
*-border-radius- Добавляет скругленные углы. Свойство присваивается в вариантах для Firefox
-moz-..., Chrome/Safari-webkit-...и стандартное CSS3-свойство для тех, кто его поддерживает (Opera). display- По умолчанию, у
Aэто свойство имеет значениеdisplay: inline. height,line-height- Устанавливает высоту и делает текст вертикально центрированным путем установки
line-heightв значение, равное высоте. Такой способ центрирования текста работает, если он состоит из одной строки. text-align- Центрирует текст горизонтально.
color,font-weight- Делает текст красным и жирным.
Лучше не присваивать свойства в JavaScript, если оформление можно вынести в CSS.
В отличие от разобранного примера, как правило, JavaScript лишь добавляет или убирает класс, а стили настраиваются уже в CSS.
getComputedStyle и currentStyle
Свойство style дает доступ только к той информации, которые хранится в elem.style.
Он не скажет ничего об отступе, определенном в CSS:
<style>
body { margin: 10px }
</style>
<body>
<script>
alert(document.body.style.marginTop)
</script>
</body>
А если мы хотим, например, сделать анимацию и плавно увеличивать отступ на 10px? Как нам сделать это? Для начала, нам надо получить текущее значение.
Для того, чтобы получить текущее значение свойства, используется метод window.getComputedStyle, описанный в стандарте DOM Level 2.
Его синтаксис таков:
getComputedStyle(element, pseudo)
- element
- Элемент, значения для которого нужно получить
- pseudo
- Псевдо-селектор, например
'hover'илиnull, если он не нужен.
Поддерживается всеми браузерами, кроме IE<9. Следующий код будет работать во всех не-IE браузерах и в IE9+:
<style>
body { margin: 10px }
</style>
<body>
<script>
var computedStyle = getComputedStyle(document.body, null)
alert(computedStyle.marginTop)
</script>
</body>
В IE до 9 версии есть свое свойство currentStyle, что почти то же самое.
Фишка в том, что currentStyle возвращает значение ‘как есть’, в тех единицах измерения, в которых он задано в CSS, а не в пикселях.
Давайте посмотрим:
<style>
body { margin: 10% }
</style>
<body>
<script>
var elem = document.body;
if (window.getComputedStyle) {
var computedStyle = getComputedStyle(elem, null)
} else {
computedStyle = elem.currentStyle
}
var marginTop = computedStyle.marginTop;
alert(marginTop);
</script>
</body>
Можно написать кросс-браузерный код и короче:
var marginTop = window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle;
Некоторые особенности этого метода:
- В Firefox пиксели могут быть дробными. Это особенность
getComputedStyleв Firefox. - В IE свойство
currentStyleсохраняет единицы измерения. Предыдущий пример выдаст проценты. Единицы измерения также сохраняются для ряда свойств в Safari (это баг).
pt,em,% в пикселиЭтот материал — дополнительный. Он не обязателен для освоения.
В IE для того, чтобы получить из процентов реальное значение в пикселях существует метод «runtimeStyle+pixel», описанный Дином Эдвардсом.
Он основан на свойствах runtimeStyle и pixelLeft, работающих только в IE.
В следующем примере функция getIEComputedStyle(elem, prop) получает значение в пикселях для свойства prop, используя elem.currentStyle и метод Дина Эдвардса.
Если вам интересно, как он работает, ознакомьтесь со свойствами с runtimeStyle и pixelLeft в MSDN и раскройте код.
function getIEComputedStyle(elem, prop) {
var value = elem.currentStyle[prop] || 0
// we use 'left' property as a place holder so backup values
var leftCopy = elem.style.left
var runtimeLeftCopy = elem.runtimeStyle.left
// assign to runtimeStyle and get pixel value
elem.runtimeStyle.left = elem.currentStyle.left
elem.style.left = (prop === "fontSize") ? "1em" : value
value = elem.style.pixelLeft + "px";
// restore values for left
elem.style.left = leftCopy
elem.runtimeStyle.left = runtimeLeftCopy
return value
}
Рабочий пример (только IE):
<style> #margin-test { margin: 1%; border: 1px solid black; } </style>
<div id="margin-test">Тестовый элемент с margin 1%</div>
<script>
var elem = document.getElementById('margin-test')
if (!elem.getComputedStyle) // старые IE
document.write(getIEComputedStyle(elem, 'marginTop'))
else
document.write('Пример работает только в IE<9')
</script>
Современные Javascript-фреймворки используют этот прием для эмуляции
getComputedStyle в старых IE.
Итого
Все DOM-элементы предоставляют следующие свойства.
- Свойство
classNameвсегда синхронизируется с атрибутомclass. - Свойство
style- это объект, в котором CSS-свойства пишутся вотТак. Он хорошо работает для записи свойств. И позволяет читать свойства заданные им или атрибутом «style», но не описанные в CSS. cssTextпозволяет получать/записывать полный набор свойств дляstyleв текстовом виде. С помощьюstyleвы не можете добавить!important, но можете сделать это сcssText.- Свойство
currentStyle(IE) и методgetComputedStyle(стандарт) позволяют получить живое значение свойств стилей, после того, как эти стили были применены.Примечания:
- Firefox может вернуть дробное значение.
- Старый IE и Safari возвращают значение в заданных единицах измерения, не приводя их к пикселям.
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.