• Страница 1 из 1
  • 1
Атрибуты и свойства: реализация, методы и отличия в Internet
Olegan Дата: Вторник, 01.05.2012, 16:33 | Сообщение # 1
  • Проверенный
  • Сообщений: 680
  • Репутация:
    19
  • Статус: Offline
Реализация атрибутов в Internet Explorer радикально отличается от той, которую предписывает стандарт DOM и которая реализована во всех остальных браузерах. Internet Explorer (здесь и далее, речь идёт о IE версии ниже 8) не различает атрибуты и свойства, что делает работу с атрибутами весьма затруднительной.
Более того, это способствует тому, что некоторые начинающие веб-программисты не понимают разницы между атрибутами и свойствами.

Этот материал объясняет назначение атрибутов и свойств и представляет примеры их использования.

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

Атрибуты и свойства в модели DOM

Для каждого тега в XML и HTML может быть указано произвольное количество атрибутов.
Атрибут представляет из себя пару строк имя/значение и задается в коде документа:
Code (HTML)


Здесь у тега input три атрибута: id, type и value со значениями textField, text и 5 соответственно.
Заметим, что в HTML регистр букв в имени атрибута не имеет значения, в отличие от XML/XHTML.

DOM позволяет читать атрибуты из скриптов с помощью методов hasAttribute() и getAttribute():
Code (HTML)



Можно и менять атрибуты, для этого существуют методы setAttribute() и removeAttribute():
Code (HTML)



В наших примерах мы работает с объектом inputTag, который соответствует тегу input документа.
У этого объекта есть ряд свойств, некоторые из которых названы так же, как и атрибуты тега:
Code (HTML)



Если судить по этому примеру, то атрибут type и свойство type ничем не отличаются.
У них всегда одно и то же значение, а результат при изменении атрибута такой же, как и при изменении свойства.
Более того, если изменить атрибут, то меняется и свойство:
Code (HTML)



Можно изменить и свойство, атрибут тоже автоматически изменится. Это связано с тем, что браузер автоматически синхронизирует значения атрибутов и свойств.
И все же они не всегда идентичны:
Code (HTML)



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

Еще более явной становится разница, если посмотреть на атрибут value и свойство value.
Code (HTML)



Здесь атрибут и свойство имеют разные значения: атрибут value определяет начальное значение для текстового поля. Текущее же значение хранится в свойстве value и меняется через него же.

Не всегда у атрибута и связанного с ним по смыслу свойства одинаковые названия. Типичным исключением является атрибут class, которому соответствует свойство className. Часто отличается и тип данных, к примеру значение атрибута onclick (как и в принципе всех атрибутов) строкового типа, а у соответствующего свойства onclick значением является функция.-

Реализация атрибутов в Internet Explorer

Разработчики IE упростили модель DOM до предела уравняв атрибуты и свойства.
В этом браузере следующие две строки абсолютно эквивалентны:
Code (HTML)



При таком подходе немедленно возникает множество осложнений.
Первое связано с тем, что регистр букв в имени свойств играет роль, в то время как в имени атрибутов он игнорируется (как минимум в HTML).
В Internet Explorer же следующие две строки вдруг приобретают разное значение:
Code (HTML)



Эти строки устанавливают два разных свойства объекта.
Возникает вопрос - что вернет в этой ситуации inputTag.getAttribute("ABRAKADABRA")?
Ответ: либо abcd1, либо abcd2.
В Internet Explorer getAttribute() ищет первое свойство с именем, которое соответствует запрошенному атрибуту за вычетом регистра букв. Если таких свойств несколько, то сложно сказать, какое именно он вернет.
›› inputTag.getAttribute("ABRAKADABRA") (проверить)

Следующее осложнение возникает с атрибутами, название которых не идентично названию свойства:
Code (HTML)



›› inputTag.setAttribute("class", "my-class") (проверить)

Эта строчка корректно изменит класс тега во всех браузерах. Лишь в Internet Explorer она установит свойство class, не имеющее никакого значение - нужное свойство называется className.
С этой проблемой сталкиваются настолько часто, что она даже заслужила упоминания в MSDN.

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

Но на этом проблемы не кончаются.
Как уже было сказано, тип атрибутов и свойств не обязательно одинаков. Чаще всего проблемы возникают при установке обработчиков событий:
Code (HTML)



›› inputTag.setAttribute("onclick", "alert('clicked')") (проверить)

После выполнения этого кода в Internet Explorer щелчки на текстовом поле не вызовут никакой реакции. Причина станет ясна, если сравнить значения свойства onclick в Internet Explorer и каком-нибудь другом браузере:
Code (HTML)



›› alert(typeof inputTag.onclick) (проверить)

Это покажет, что Internet Explorer записал в свойство onclick строку, в то время как другие браузеры корректно преобразовали значение атрибута в функцию.
А при возникновении события Internet Explorer не находит в свойстве onclick функции, которую можно выполнить.
Чтобы присвоить обработчик события в Internet Explorer надо написать:
Code (HTML)



›› inputTag.setAttribute("onclick", function() {alert('clicked')}) (проверить)

Стандарт DOM, однако, явно предписывает, что второй параметр метода setAttribute() является строкой.
Такой код, опять же, не станет работать ни в одном браузере, корректно реализующем стандарты.

Выводы

Проще всего, конечно, вообще отказаться от использования атрибутов и пользоватьсятолько свойствами. Для большинства приложений этого достаточно, но существуют задачи, где без атрибутов не обойтись (к примеру копирование DOM-дерева с параллельным его изменением).
В таких случаях можно выполнять для Internet Explorer другой код, который дает похожий результат (возможно, не идеальный, но лучше, чемвообще никакого результата):
Code (JavaScript)
document.body.setAttribute("class", "attribute-test");
if (document.body.className == "attribute-test")
{
// Атрибуты работают корректно (не Internet Explorer или исправленная версия)
// Работаем с атрибутами
}
else
{
// Использовать атрибуты нельзя (Internet Explorer версии меньше 8)
// Альтернативный код только для Internet Explorer
}
 
  • Страница 1 из 1
  • 1
Поиск: