Кроссбраузерное получение стиля

Забегая вперед, для экономии Вашего времени выкладываю готовый кусок универсального кода получения стиля, например, ширины элемента:

element=document.getElementById('aa');
var c=window.getComputedStyle(element, null);
s.style.width=parseInt(c.width)+"px";

Почему так сложно? Почему нельзя просто написать [element].style.width?

Проблема связана с тем, что стили определенного элемента будут доступны в JavaScript через конструкцию [element].style только в двух случаях:

  1. Если стили были прописаны в атрибуте style соответствующего тега. Например:
    <div style="position:absolute; top:5px"></div>
    В случае этого примера через JavaScript будут доступны значения свойств [element].style.position и [element].style.top, а остальные свойства (в т.ч. установленные через CSS) будут недоступны.
  2. Если стили были установлены через JavaScript, то они будут доступны везде, ведь на самом деле объект [element].style отражает состояние атрибута style соответствующего тега.

Если вам сложно понять, в чем же заключается проблема, взгляните на этот пример:

<style type="text/css">
    .someClass {
        margin-left: 15px;
        cursor: pointer;
    }
</style>
<div onclick="alert(this.style.marginLeft || 'Нету :(')" class="someClass">Нажми на меня</div>

РЕЗУЛЬТАТ:

Нажми на меня

Как видите, хотя CSS-свойство margin-left и повлияло на отображение, его "нету" в объекте [element].style.

Справиться с этой проблемой можно, получив значения из "вычисленного" стиля элемента. В соответствии с названием, это будет метод getComputedStyle.

Метод getComputedStyle

В W3C-браузерах у объекта window доступен метод getComputedStyle, который принимает два параметра: сам элемент, стили которого мы хотим получить, и "псевдо-элемент". Второй параметр обязателен и для простых элементов должен быть пустой строкой или null. А вообще, этот параметр работает по аналогии с "псевдо-классами" в CSS, т.е. может принимать параметры "hover", "visited" и подобные.

Этот метод возвращает объект CSSStyleDeclaration, другими словами, объект такого же типа, как и [element].style, но в данном случае мы не можем менять свойства этого объекта, а только получать их значения.

Вот переделанный пример, подобный тому, что был представлен выше:

<style type="text/css">
    .someClass {
        margin-left: 15px;
        cursor: pointer;
    }
</style>
<div onclick="alert(window.getComputedStyle(this, null).marginLeft)" class="someClass">Нажми на меня</div>

РЕЗУЛЬТАТ:

Нажми на меня

Стоит отдельно отметить, что getComputedStyle возвращает действительные значения стилей, которые будут изменяться в соответствии с изменением свойств объекта [element].style.

Если в вашей задаче необходимо узнать значения вычисленных свойств "по-умолчанию", то вы можете вызвать метод getComputedStyle у объекта document.defaultView с теми же параметрами, в результате получив вычисленные значения свойств, строго указанных в CSS или внутреннем стиле элемента.

Как работать со свойствами стилей

Очень просто получать значение текущего вычисленного стиля:

var computedStyle = window.getComputedStyle(element, null);

В скриптах, которые будут изменять свойства стилей элементов, лучше реализовать следующий принцип работы:

Если свойство стиля, с которым будет производиться работа, недоступно в объекте [element].style, получаем его из текущих вычисленных стилей и "запоминаем", или обновляем соответствующее свойство в [element].style. После этого нам уже не нужно обращаться к действительным стилям, ведь значение интересующего нас свойства будет соответствовать значению в [element].style.

Единицы измерения

Вторая проблема, с которой сталкиваешься при работе со свойствами стилей, заключается в том, что при изменении значений определенных свойств из JavaScript, нужно указывать единицы измерения вместе с числовым значением.

Обычно, если мы хотим переместить какой-то элемент, то мы получаем его текущее положение и прибавляем к нему определенное значение. Но значения в CSS хранятся в виде строки, например "15px". Поскольку в JavaScript оператор "+" производит конкатацию, если один из элементов операции - строка, то обычные операции, как с числами, тут не сработают:

var a = "15px";
a++; // NaN - not a number

var a = "15px";
a += 5; // 15px5

var a = "15px";
var b = a + 7; // 15px7

И наоборот, если мы попытаемся обновить свойство, приравняв ему число, то в режиме следования стандартам ничего не произойдет, так как не указаны единицы измерения.

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

В общем виде, работа должна происходить так:

// Допустим, мы работаем с каким-то элементом,
// для которого доступен style.top:
var top = parseInt(element.style.top); // Получили число из строки

top++; // Увеличили его на единицу

// Так как "px" строкового типа, то произойдет
// конкатация и будет записано правильное значение
// с единицами измерения:
element.style.top = top + "px";

Обратите внимание, что в последней строке мы можем сделать вот так:

element.style.top = top + 25 + 100 + "px";

Потому что при последовательном вычислении выражения конкатенация произойдет только в последнюю очередь, а выражения слева от строки будут складываться, как числа.

Оригинал: http://javascript.ru/blog/Andrej-Paranichev/Osnovy-programmnoj-animacii-JavaScript


.