DOM: свойства VS атрибуты
У DOM-элементов в javascript есть свойства и атрибуты. И те и другие имеют имя и значение.
Поэтому иногда разработчики путают одно с другим.
Между ними есть соответствие, но оно не однозначное и его лучше понимать.
Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можно назначить свойство, используя обычный синтаксис.
var elem = document.getElementById('MyElement')
elem.mySuperProperty = 5
Значением свойства может быть любой объект. Это же javascript.
elem.master = {
name: vasya
}
alert(elem.master.name)
Теперь посмотрим на DOM-элемент с другой стороны. Являясь элементом HTML,
DOM-элемент может иметь любое количество атрибутов.
В следующем примере элемент имеет атрибуты id, class и нестандартный (валидатор будет ругаться) атрибут alpha .
<div id="MyElement" class="big" alpha="omega"></div>
Атрибуты можно добавлять, удалять и изменять. Для этого есть специальные методы:
setAttribute(name, value)
- Устанавливает значение атрибута
getAttribute(name)
- Получить значение атрибута
hasAttribute(name)
- Проверить, есть ли такой атрибут
removeAttribute(name)
- Удалить атрибут
Имя атрибута является регистронезависимым.
// название маленькими буквами
document.body.setAttribute('test', 123)
// большими буквами
document.body.getAttribute('TEST') // 123
Значением атрибута может быть только строка. Это же HTML..
Все, вроде бы, ясно. Есть свойства. Есть атрибуты.
Но создатели javascript решили (с лучшими намерениями) запутать ситуацию и создать искусственное соответствие между свойством и атрибутом.
А именно, браузер синхронизирует значения ряда свойств с атрибутами. Если меняется атрибут, то меняется и свойство с этим именем. И наоборот.
Например:
document.body.id = 5
alert(document.body.getAttribute('id'))
А теперь - наоборот
document.body.setAttribute('id', 'NewId')
alert(document.body.id)
Такая синхронизация гарантируется для всех основных стандартных атрибутов.
При этом атрибуту с именем class соответствует свойство className , т.к. ключевое слово class зарезервировано в javascript.
Для "левых" атрибутов браузер ничего не гарантирует
document.body.setAttribute('cool', 'SomeValue')
alert(document.body.cool) // undefined везде кроме IE (почему - см ниже)
- Название атрибута не зависит от регистра
-
Атрибуты с именами "abc" и "ABC" - один и тот же атрибут.
document.body.setAttribute('abc', 1)
document.body.setAttribute('ABC', 5)
alert(document.body.getAttribute('abc')) // => стало 5
Но свойства в разных регистрах - два разных свойства.
document.body.abc = 1
document.body.ABC = 5
alert(document.body.abc) // => все еще 1
Увы, в Internet Explorer версии до 8.0 с этим проблемы. Этот браузер старается по возможности уравнять свойства и атрибуты. Но как быть, если свойства - регистрозависимы, а атрибуты - нет?
Создатели IE поступили хитро: setAttribute ставит оба свойства (abc и ABC ).. Ну а getAttribute возвращает первое попавшееся из них, с учетом регистронезависимости. Если таких свойств несколько, то невозможно сказать, какое именно он вернет.
document.body.setAttribute('abc', 1)
document.body.setAttribute('ABC', 5)
// IE пытается уравнять свойства и атрибуты
alert(document.body.abc) // => 1
alert(document.body.ABC) // => 5
// но getAttribute выбирает первое попавшееся свойство
// за вычетом регистра букв
alert(document.body.getAttribute('abc')) // => 1
alert(document.body.getAttribute('ABC')) // => 1
Запустите этот пример в IE6/7 и, например, в Firefox, чтобы лучше понять различия.
Атрибут можно установить любой, а свойство - нет
Например, можно установить для тэга <body> атрибут tagName , но соответствующее свойство - только для чтения, поэтому оно не изменится:
document.body.setAttribute('tagName',1)
document.body.getAttribute('tagName') // 1
document.body.tagName // "BODY"
Вообще говоря, браузер не гарантирует синхронизацию атрибута и свойства.
Атрибуты и обработчики событий
В IE текстовое значение, присвоенное атрибуту onclick , не является функцией и не будет работать:
elem.setAttribute('onclick', 'alert(something)') // в IE не работает
Firefox корректно преобразовывает строку в функцию, поэтому там этот фрагмент работать будет. Но, вообще говоря, никакой браузер не обязан этого делать.
Атрибут - это строка (кроме IE)
Следующий код это наглядно демонстрирует:
document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE
В первой строке атрибуту присвоено значение-объект. Firefox тут же автоматически преобразовал его в строку. А IE, в нарушение стандартов, оставил атрибут объектом.
Исключение className
Как уже говорилось в разделе о синхронизации, атрибуту class соответствует свойство className . Так получилось из-за того, что class является зарезервированным словом javascript.
В IE также является исключением атрибут for , для него используется свойство forHtml .
Cвойство элемента и атрибут - это разные вещи. Не используйте одно вместо другого.
Вообще, обычно свойств хватает с головой.
|
Атрибуту for тега <label> соответствует свойство htmlFor:
Например, атрибут value и свойство value элементов ввода не синхронизируются браузером. Важно изменять именно значение атрибута, чтобы обеспечить корректность поиска элементов:
ничего не понятно из статьи ((((((
все как-то не систематично и непонятно
какие-то свойства и атрибуты
что это вообще такое?
to:
Автор: anonimus (не зарегистрирован), дата: 31 октября, 2013 - 03:10
Может, для начала следовало бы линки да книжки по HTML почитать?
Во-вторых, почитав несколько статей сайта по очереди советую и вам того же - тогда поймете, хотя бы почему в каждой статье не разжевывается одно и то же понятие (хорошо, кстати, разжеванное в более ранней статье)
Смотри братуха, вот что здесь сказано: Имена свойств регистрозависмые а имена атрибутов ето ключи обьекта и не чувствительны к регистру. В СУБД MYSQL установленной на операционной системе Windows тоже самое с именами атрибутов обьекта, то есть с именами ключей-атрибутов таблицы реляционных данных.
Так и не понял что такое атрибут и свойство((((
Свойство - это атрибут с четко зафиксированным смыслом. Этот смысл жестко привязан к имени свойства (size - это свойство размера). Атрибут - более широкое понятие. Это пользовательские данные, если угодно. В том смысле, что пользователь может вводить свои атрибуты с произвольными именами, и сам назначать им смысл. (названия таких доп. Атрибутов не могут совпадать с именами Свойств).
Обновил статью. Надеюсь, стало понятнее.
Огромное спасибо!
Первая строка статьи очень полезная .
мне кажется вы слегка усложняете понятия свойства и атрибута ( как и автор статьи ), при всём уважении к вам )). Мне кажется надо по конкретнее и по проще (кстати , автору слегка это удалось , когда он привел в пример такие атрибуты как class , id ) , типа , атрибуты - это атрибуты html тэгов , например : id, class, style, (и иногда) margin background celpadding cellspasing href и т.д. А свойства - это свойства элементов(тегов) в javascript-е , которые необходимы для работы(манипулирования) с этими "тэгами" через программу(javascript) .
PS. В интернете действительно нет нормальных самоучителей и учебников по которым можно учиться . Есть только хорошие справочники Я думаю, это единственный ресурс по которому возможно учиться
Выходим из анабиоза, отличных учебников полно - Флэнаган, ppk, и т.д. Сколько можно ныть про отсутствие, вместо того чтобы нормально постараться поискать. Острочертело уже.
в приведённых Вами учебниках много ненужной воды. Лучше суть понять читая такие краткие и понятные статьи, а уж потом читать макулатуру, уже отталкиваясь от уже уяснённой модели.
Мне кажется, проще сказать, что свойства в JavaScript аналогичны свойствам в любом объектно-ориентированном языке. С тем исключением, что иногда свойства получают те же значения, что и атрибуты. Но не всегда.
И еще мне кажется, что лучше пользоваться этой связью насколько возможно меньше. Атрибуты получать и устанавливать через getAttribute и setAttribute соответственно, в обход свойств. Меньше путаницы в итоге получится.
Автор же ясно дал понять, что свойств хватает с головой,
т.е. атрибуты лучше не использовать, и они не нужны
Вот теперь понятно))) Краткость - сестра таланта. Спасибо за пояснение. Огромное Спасибо Автору))
Спасибо за 1-вый комментарий!Теперь точно понял.
Вот тут Cy1on идеально всё объяснил. Со статьи сложно было понять, а после прочтения комментария стало всё ясно.
Отличная статья!
Я легко и быстро понял разницу.
Это именно то, что нужно.
Тема IE не раскрыта, первый пример из раздела "Название атрибута не зависит от регистра" в ИЕ выведет как раз таки 1, а не 5.
Кто хочет раскрыть для себя особенности работы IE со свойствами и атрибутами, читать http://xpoint.ru/know-how/JavaScript/Atributyi?8
Улучшил раскрытие темы IE в статье, добавил соответстсвующий пример.
У меня Windows 7 + IE 8
IE8 (сборка 7100) выдал не 5, как в примере, а undefined, как и firefox 3.5.3
Да, там это правили. Пофиксил в статье, спасибо.
Здравствуйте.
У меня для "левого" атрибута вывел значение SomeValue, а не undefined.
Это нормально?
да, там же сказано Для "левых" атрибутов браузер ничего не гарантирует... только я вот лично не догал что подразумевается под "левыми".. если "левый" == придуманный автором программы то почему он рботает в следующем же примере!?
в примере выше Вы оперируете свойствами.
Автор имеет в виду, что не гарантированно, что
если у вас в хтмл-коде написано:
то
alert(document.getelementbytag('a').balalayka) выдаст Вам mumu
В примере
document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE
Как [object Object] доказывает что Firefox преобразовал объект в строку?
Функция Object.prototype.toString() возвращает результат в виде [object, классОбъекта]. Соответственно для объекта {a:5} toString() вернул [object Object]. Ссылка на спецификацию
Достаточно непонятно....
А если в FF написать alert(document.body.getAttribute('v').a) ? Мне кажется, что будет 5...
А я столкнулся вот с чем:
В html есть, например, элемент
Данный пример не корректно работает в ИЕ (атрибут class="head" появляется, но не вступает в силу), зато работает во всех остальных браузерах:
результат:
Зато в ИЕ работает следующий код:
результат в ИЕ:
результат в остальных браузерах:
может не 'link' a 'head'
В IE в теге label используется for для того, чтобы обозначить id элемента формы, который будет давать этому элементу фокус (т.е., щелкните на галочке, и пунктиром выделится не только она, но и надпись label с этим свойством)
Надо поправить статью! А точнее подкоректировать коментарии...
Здесь:
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE
В первой строке атрибуту присвоено значение-объект. Firefox тут же автоматически преобразовал его в строку. А IE, в нарушение стандартов, оставил атрибут объектом.
Если так, то должно быть так?:
// "[object Object]" в IE
// 5 в Firefox
NarKoZ, Вы не правы.
Как ранее написал BlueIce, "[object Object]" - это не указание на то, что перед нами объект, а лишь результат преобразования элемента в строку (читайте выше).
А вот строка
alert(document.body.getAttribute('v').a) // 5 в IE
как раз указывает на существование объекта document.body.getAttribute('v').a.
Не хватает конкретных примеров. Всё равно до конца не понятно отличие свойств и атрибутов. Что и в каких случаях лучше с точки зрения стандартов использовать: свойства или атрибуты? Например: id, class, style... Работает и через свойства, и через атрибуты. выше более-менее конкретно написал насчёт атрибутов. Это действительно так? И когда нужно применять не атрибуты, а свойства? Хотелось бы увидеть конкретные примеры, а не описание, в каких случаях они друг друга заменяют, а в каких нет.
По-моему разработчики javascript ничего не запутали. Запутывает скорее статья.
Немного "тупой" вопрос - если есть страница с примененными к ней CSS стилями, то, чтобы прочитать значение заданное стилем для тега (например: div {width: 400px}), надо использовать обращение к атрибутам (getAttribute(name))?
Вот этот пример, к слову, в IE8 выдаёт результат '1'.
document.body.setAttribute('abc', 1)
2
document.body.setAttribute('ABC', 5)
3
alert(document.body.getAttribute('abc')) // => стало 5
Может, потому что это не стандартное свойство? Или очередной косяк эксплорера?
А у меня такой вопрос-не совсем в тему.
Я желаю расширить функционал некоторых элементов,например Table и т.д.,добавив новые свойства и атрибуты.
Но известно,что Javscript и Dom-направление развиваются,изменяется,соответственно и интерпретатор Javascript Браузеров
Что если в следующей спецификации Javascript имя нового свойства какого-нибудь элемента будет совпадать с именем моего пользовательского атрибута или свойства?Тогда сайт будет некорректно работать?То есть в одно прекрасно утро мой сайт просто перестанет работать...А мне придется переделать кучу кода.(А я планирую сделать несколько "весомых" сайтов.
Как избежать такой проблемы?
Не надо так делать. Пишите свои функции и библиотеки, но собственные свойства у встроенных объектов - давно моветон.
Правильно ли я Вас понял,что лучше разработать свой собственный элемент типа table(что безусловно является трудоемким процессом,тем более что это будет практически его копия-что представляется сверхиррациональным-в плане развития языков высокого уровня) ради избежания вышеописанной проблемы?Или на худой конец лучше как то обойтись без создания собственных элементов но и одновременно не расширять функционал стандартных элементов(что приведет зачастую к сильному усложнению логики кода,как и его объема)?
Этот вопрос и впрямь намного более общий, чем рассуждение о DOM и Javascript.
Есть ровно два соображения по этому поводу.
Во-первых, для создания продуктов следует использовать среду, облегчающую массовое переименование.
Во-вторых, не стоит экономить на названиях свойств, атрибутов, функций и чего угодно ещё. Например, в название атрибута можно включить название сайта или собственный ник разработчика. Вряд ли творцам спецификаций придёт в голову использовать Ваш ник при очередном дополнении языка Javascript. :-)
Спасибо, толково расписал сложный вопрос!
Ёмоё, ну правда, запутано
"Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можно назначить свойство, используя обычный синтаксис."
Смысл написанно: Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можнозадать значение какого либо из имеющихся свойств, используя обычный синтаксис.
Я правильно понял?
P.S. Кстати таких логических ловушек (с неоднозначной трактовкой) много. Понятно дело усвоение материала страдает.
Комментарий "Автор: Cy1on (не зарегистрирован), дата: 30 июля, 2009 - 15:20 " практически полностью расшифровывает всю путаницу в статье. Было бы прекрасно если б автор статьи "отрехтовал" статью (всю статью) со смыслом этого комментария. Или где либо (в логически обоснованном месте статьи) вставил данный комментарий полностью. От себя: возможно комментарий нужно доработать, например "Свойство - это атрибут узаконенный (закрепленный спецификацией, занесённый в спецификацию как неотъемлемое описание узла-элемента) с четко зафиксированным смыслом на который указывает названием (имя) данного свойства и возможными (а иногда фиксированными) значениями .... и т.д."
document.body.setAttribute('abc', 1)
document.body.setAttribute('ABC', 5)
// IE пытается уравнять свойства и атрибуты
alert(document.body.abc) // => 1
alert(document.body.ABC) // => 5
// но getAttribute выбирает первое попавшееся свойство
// за вычетом регистра букв
alert(document.body.getAttribute('abc')) // => 1
alert(document.body.getAttribute('ABC')) // => 1
Мой FF версии 5.0 выдает пустыми первые два окошка и пятерки в следующих двух. По-моему что-то не так)
Не понял, тут все перемешано насчет свойства и атрибута. Конкретно, что имеется ввиде под свойством и атрибутом?
В FF столкнулся с такой вот проблемой:
Создаю программно(В скрипте) миню(XUL), В меню нужно выдилить строку, непрограмно это так выглядит
Так вот, програмно создав минюшку, програмно добавляю этот атрибут, потом програмно меняю свойство disabled и всё(((( Больше через свойства доступа нет, выходит так что есть отдельно свойство и отдельно атрибут с одинаковыми именами. Всё дело в том что браузер не успел создать свойство, по подобию атрибута, а точнее несоздавал его, потому что он создаёт свойство только при визуализации меню.
Если например после создания менюшки в скрипте, я мышкой повожу на меню посмотрю его, а потом уже меняю свойство то всё работает так как мне надо, свойство и атрибуты скреплены) Но если я создам атрибут, а потом хоть что буду делать но непосмотрю визуально менюшку, и начну править свойство то создастся обсолютно независимое свойство. Конечно я могу программно просто править атрибуты, но мне интересно есть ли какой способ заставить браузер с помощью скрипта синхранизировать атрибуты и свойства??? и/или как напрямую привязать атрибут к свойству??
скажите плз что означает VS
и второй вопрос что означает "[object Object]"
где об этом написано?
VS - это тоже самое что 'и', '&', 'And'
VS как бы объединяет текст или значение (Смысл)
Потап VS Настя Каменски
Потап и Настя Каменски.
vs (иногда с точкой иногда без точки) сокращение от латинского слова versus (против). Так что Потап против Насти
а можно ли как нибудь узнать какие у элемента есть атрибуты (к примеру в виде массива)?
статья на мой взгляд не очень
В сафари с айпада данный код работает иначе
document.body.setAttribute('abc', 1)
document.body.setAttribute('ABC', 5)
alert(document.body.abc) // => 1
alert(document.body.ABC) // => 5
// но getAttribute выбирает первое попавшееся свойство
alert(document.body.getAttribute('abc')) // => 1
alert(document.body.getAttribute('ABC')) // => 1
Get attribute сафари выбрал первый, потом заменил вторым, и первые два значения свойства он выдал как undefined, а остальным двум атрибутам он присвоил 5 так как оно было последним значением аттрибута.
спасибо за понятные статьи. Правда иногда сложновато понять что имеет ввиду автор если это не выделено, например непонятно было в начале статьи чтоже все таки такое свойство, но к середине уже стало ясно
Вот тут вы говорите чтобы отказаться от использования аттрибутов
Но как же dojo там одни аттрибуты
и далее по списку
Вы чего серьезно отказаться решили
Почему все примеры "однобокие" и завязаны за дескриптором body? А если нужно получить или задать атрибуты у другого тэга
Молодец.
elem.mySuperProperty = 5
Это свойство. Как узнать, что это не атрибут?
Атрибуты можно назначать только через метод setAtribute?
отличная статья , все четко и понятно
Интересная статья. Вопрос: как поймать событие установки объекту атрибута. Например, disable для
тэг < "div" > сожрал
Здравствуйте! Может я не в тему спрошу. Заранее извините. Как в document.body.setAttribute('abc', 1), вместо 'abc' подставить значение переменной. Например:
$name_attrib="id_elem";
document.body.setAttribute($name_attrib, 1);
Так не работает.
>Автор: Бо (не зарегистрирован), дата: 20 октября, 2011 - 10:34 #permalink
>Статья, норм, автору зачот!
>Но если говорить откровенно, для того чтобы понять разницу между атрибутом и >свойством достаточно знать, что у объекта есть свойства а у тэга - атрибуты.
>Т.е. если рассматривать тэг то id это атрибут(как сказал бы автор:"Это же >HTML..."), а если рассматривать объект а DOM , то id это свойство (как сказал бы >автор: "Это же javascript...")
т.е. пока HTML нераспарсен (не преобразован) в DOM модель броузера:
HTML - состоит из тегов содержащих атрибуты,
после преобразования HTML в модель DOM - броузер содержит объекты со свойствами доступными через javascript.
т.е. свойства объектов DОМ модели заполняются (проецируются) из атрибутов тегов HTML.
т.к. атрибутов у тегов мало, то часть свойств объектов DOM заполняются по умолчанию или наследуются.