Изменение стилей элементов
Оглавление
Поддержка
Динамическое изменение стилей элементов поддерживается почти в одинаковой форме всеми современными браузерами: Internet Explorer 4+, Mozilla 1.0+ (соответственно Netscape 7.0+, все версии Firefox и т.д.) и Opera как минимум с версии 7.20.
Изменение класса элемента
Самый простой и надёжный способ изменить отображение элемента - это изменение его класса, то есть свойства className. Пример:
<html> <head> <style type="text/css"> .class1 { color: white; background-color: black; } .class2 { color: blue; background-color: green; } </style> </head> <body> <div onclick="this.className = (this.className == 'class2' ? 'class1' : 'class2')"> Click here multiple times </div> </body> </html>
Напомним, что элементу можно присвоить более одного класса, для этого нужно просто разделить их названия пробелом.
Преимущества этого подхода:
- можно менять несколько CSS-свойств одновременно
- в JavaScript используются только названия классов, CSS-код определён отдельно
- изменения легко обратимы, достаточно вернуть старое значение класса
Недостаток:
- Стили предопределены, соответственно количество возможностей ограничено
Нередко стили используют для того, чтобы динамически передвигать элементы с абсолютным позиционированием; для этого переопределением класса элемента не обойтись.
Пример реализации
К сожалению, в стандарте DOM нет никаких механизмов для работы с множеством классов элемента — есть только свойство className, напрямую отображающее атрибут class — т.е. строку с пробелами. Предлагаемый объект-обёртка позволяет облегчить работу с множественными классами.
// класс-обёртка, явным образом обычно не создаётся (см. ниже) function CssClassesHandler(object) { this.object = object } CssClassesHandler.prototype = { object : null, // возвращает все классы элемента в виде массива строк all : function() { return this.object.className.split(/\s+/) }, // назначен ли элементу данный класс? exists : function(className) { var classes = this.all() for(var i = 0; i < classes.length; i++) if(classes[i] == className) return true return false }, // назначает элементу класс add : function(className) { var classes = this.all() for(var i = 0; i < classes.length; i++) if(classes[i] == className) return this.object.className = this.object.className + " " + className }, // удаляет класс из назначенных элементу. // можно указать как имя класса, так и регулярное выражение, // которое будет сравниваться отдельно с каждым из назначенных классов. remove : function(className) { var classes = this.all() var cn = "" for(var i = 0; i < classes.length; i++) { var isMatch = (typeof className.test == "function") ? className.test(classes[i]) : (classes[i] == className) if(!isMatch) cn = cn + " " + classes[i] } this.object.className = cn.substr(1) }, // назначает/удаляет класс в зависимости от булевского параметра state set : function(className, state) { if(state) this.add(className) else this.remove(className) }, // назначает элементу класс, если он ещё не назначен, в противном случае удаляет flip : function(className) { if(this.exists(className)) this.remove(className) else this.add(className) } } // функция, создающая класс-обёртку для данного элемента function CssClasses(object) { return new CssClassesHandler(object) }
Пример использования:
div = document.getElementById('someId') CssClasses(div).add('someClass') CssClasses(div).remove('someClass') CssClasses(div).flip('someClass')
Изменение индивидуальных стилей элементов
У всех HTML-элементов есть свойство style. С его помощью можно легко менять стили, которые указаны для элемента в HTML-атрибуте style:
var element = document.getElementById('testElement'); element.style.left = '400px'; element.style.marginTop = '10px'; // Следующая строчка не покажет ничего, если элементу не задать display в атрибуте style alert(element.style.display);
Свойства объекта style названы так же, как и соответствующие CSS-свойства, но пишутся без дефисов, а следующие за дефисом буквы переведены в заглавный регистр (так из margin-top получилось marginTop). Все свойства доступны для чтения и записи, но читается/меняется при этом исключительно значение атрибута style этого элемента. То есть, читать действующие на данный момент стили элемента нужно иначе.
Доступ к действующим стилям элементов
К сожалению, для определения действующих стилей помимо стандарта DOM2 существует ещё реализация, которая используется в Internet Explorer. DOM2 определяет метод getComputedStyle() объекта document.defaultView, который возвращает действующие стили для комбинации элемента и псевдо-элемента (к примеру, 'hover' или 'active'):
var element = document.getElementById('testElement'); var computedStyle = document.defaultView.getComputedStyle(element, null); alert(computedStyle.display);
В Internet Explorer вместо этого у каждого элемента есть свойство currentStyle, аналогичное свойству style, но содержащее все действующие стили. Возможность учитывать псевдо-элементы в этом варианте отсутствует. То есть, код, аналогичный предыдущему, выглядел бы в IE так:
var element = document.getElementById('testElement'); alert(element.currentStyle.display);
К счастью, оба варианта несложно объединить. Достаточно написать в начале скрипта:
if (typeof document.defaultView == 'undefined') document.defaultView = {}; if (typeof document.defaultView.getComputedStyle == 'undefined') { document.defaultView.getComputedStyle = function(element, pseudoElement) { return element.currentStyle; } }
После этого можно везде пользоваться функцией document.defaultView.getComputedStyle() - если не использовать псевдо-элементы, всё будет работать правильно в любом браузере, в принципе поддерживающем доступ к действующим стилям.
Изменение таблиц стилей
Иногда стили нужно менять для многих элементов одновременно, что делается проще всего изменением определений в таблице стилей. Эта тема обсуждается в статье Работа с таблицами стилей.
![[logo]](/site/images/logo.jpg)