Xpoint
   [напомнить пароль]

Изменение стилей элементов

Оглавление

Поддержка

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

Изменение таблиц стилей

Иногда стили нужно менять для многих элементов одновременно, что делается проще всего изменением определений в таблице стилей. Эта тема обсуждается в статье Работа с таблицами стилей.

Powered by POEM™ Engine Copyright © 2002-2005