Оглавление
Поддержка
Динамическое изменение стилей элементов поддерживается почти в одинаковой форме всеми современными браузерами: 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() - если не использовать псевдо-элементы, всё будет работать правильно в любом браузере, в принципе поддерживающем доступ к действующим стилям.
Изменение таблиц стилей
Иногда стили нужно менять для многих элементов одновременно, что делается проще всего изменением определений в таблице стилей. Эта тема обсуждается в статье Работа с таблицами стилей.