webew
Войти » Регистрация
 
JavaScript :: DOM

Получаем значения свойств элементов - getComputedStyle

5 декабря 2008, 17:36

В ходе обработки HTML-страницы браузер вычисляет значения множества свойств для всех элементов и, исходя из этого, отображает их на странице. Научимся получать значения этих свойств.

getComputedStyle

DOM2 обеспечивает возможность взаимодействия с CSS, в том числе и возможность чтения вычисленных СSS-свойств элемента с помощью метода getComputedStyle.

По стандарту, метод getComputedStyle объекта window возвращает объект типа CSSStyleDeclaration, с помощью методов которого можно получить значения интересующих нас свойств. Чтобы предыдущее предложение стало более понятным, рассмотрим пример:

<a id="linkId" href="#">Link</a>

<script type="text/javascript">
window.onload = function() {
    // Создаем экземпляр объекта типа CSSStyleDeclaration для ссылки с идентификатором linkId
    var cs = window.getComputedStyle(document.getElementById('linkId'), "");
    // Получим значение свойства color для ссылки с помощью метода getPropertyValue
    alert(cs.getPropertyValue("color"));
}
</script>

Метод getComputedStyle принимает два аргумента: ссылку на элемент и текстовую переменную с указанием псевдо-элемента. В данном примере, в качестве второго аргумента можно было указать ":after" и получить цвет соот-его псевдо-елемента.

currentStyle

И всё бы хорошо, если бы не одно НО!, а оно у нас почти всегда одно — браузер Internet Explorer. Товарищи их Майкрософта всегда плевали на стандарты и спецификации, и этот раз тоже не стал исключением. Вышеприведенный код не будет работать в ИЕ7 и ниже (насчет IE8 — время покажет), т.к. в эксплорере нет реализации метода getComputedStyle. Вместо него у элементов в IE есть свойство currentStyle, которое возвращает объект с хешом имя_свойства=значение_свойства.

Чтобы как-то поправить положение, напишем фикс для IE, добавляющий метод getComputedStyle для объекта window и метод getPropertyValue для объекта, который вернет getComputedStyle:

if (!window.getComputedStyle) {
    window.getComputedStyle = function(el, pseudo) {
        this.el = el;
        this.getPropertyValue = function(prop) {
            var re = /(\-([a-z]){1})/g;
            if (prop == 'float') prop = 'styleFloat';
            if (re.test(prop)) {
                prop = prop.replace(re, function () {
                    return arguments[2].toUpperCase();
                });
            }
            return el.currentStyle[prop] ? el.currentStyle[prop] : null;
        }
        return this;
    }
}

С этим фиксом вышеприведенный код работает кроссбраузерно. Попробуем вывести еще пару свойств:

window.onload = function() {
    var cs = window.getComputedStyle(document.getElementById('linkId'), "");
   
    var out = "";
    out += "color:" + cs.getPropertyValue("color") + "\n";
    out += "float:" + cs.getPropertyValue("float") + "\n";
    out += "background-color:" + cs.getPropertyValue("background-color");
    alert(out);
}

Страница с примером.

Камрад Octane очень верно заметил, что currentStyle в IE принимает ключи, записанные верблюжим шрифтом, поэтому необходимо преобразование вида border-color -> borderColor, которое прекрасно работает в нашем IE-фиксе.

Проверено в: IE7, FF2, FF3, Opera 9.5, Safari 3, Chrome 0.2.


© Все права на данную статью принадлежат порталу webew.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

Octane

Не все так просто :-) «currentStyle» в IE работает с ключами вида: «borderColor», «backgroundColor», «borderBottomStyle». А используя «getComputedStyle» нужно указывать CSS-свойства: «border-color», «background-color», «border-bottom-style». Поэтому нужно еще писать функцию преобразования.

document.body.currentStyle['background-color'] // «undefined»
document.body.currentStyle.backgroundColor // «transparent» или цвет фона <body>


И еще исключением, при преобразовании, будет свойство «float», которое дожно превратиться в «styleFloat» для IE или «cssFloat», если выполняем преобразование в другую сторону.

06.12.2008, 01:36
Ответить

bur

Трудно недооценить ваше замечание. Спасибо огромное! Скрипт исправлен и немного дополнена статья - теперь всё работает прекрасно. Единственное что мне осталось неясно - это styleFloat и cssFloat, можете поделиться источником, где описаны эти свойства?
07.12.2008, 19:21
Ответить
NO USERPIC

Octane

Источник уже не помню, но насколько я понял, слово «float» зарезервировано, так сказать на будущее, на случай появления соответствующего типа данных, поэтому используется «styleFloat» в IE и «cssFloat» в других браузерах.

node.style.cssFloat // W3C
node.style.styleFloat // IE


Что-то я сам не додумался до такого регулярного выражения :-( А для чего там {1,1}?
Я решал эту проблему таким путем:

props: {
    'float': 'styleFloat'
},
prop: function(str) {
    if(this.props[str]) return this.props[str];
    if(/-/.test(str)) {
        var array = [];
        str.split('-').forEach(function(el, index) {
            array.push(index ? el.charAt(0).toUpperCase() + el.substr(1) : el);
        });
        return array.join('');
    }
    return str;
},

Интересно какой способ работает быстрее, предполагаю, что ваш :-)
07.12.2008, 22:14
Ответить

bur

{1,1} избыточно, поменял на {1}

Судя по forEach вы юзаете какой-то фреймворк...
Регэкспы - не самый производительный механизм, а у вас нагромождение из split-push-join + прохождение в цикле. Неизвестно что быстрее, но проверять лень :-)

Регэкспы мне нравятся больше из-за своей лаконичности и масштабируемости.

Думаю можно не заморачиваться на выборе способа :-)
08.12.2008, 13:37
Ответить
NO USERPIC

Octane

bur
{1,1} избыточно, поменял на {1}

Помоему в регулярном выражении еще можно упростить
var expr = /-([a-z])/g;

и тогда в функции
return arguments[1].toUpperCase();

вроде работает :-)

bur
Судя по forEach вы юзаете какой-то фреймворк...

Метод «forEach», как native-функция, есть уже во всех современных браузерах, кроме IE
Array.prototype.forEach(function(element, index, array) {}, context)
08.12.2008, 16:03
Ответить

garinov

Функция некорректна по отношению к свойствам вида -moz-opacity. Они проверяются без модификаций: el.currentStyle['-moz-opacity'].
22.12.2018, 15:29
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: