DOM: свойства VS атрибуты

Форум

Учебник Node.JS скринкаст Стандарт языка

Справочник

Discord чат

 
Статьи Тест знаний Аналоги функций PHP

Курсы javascript

 

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/attributes-and-custom-properties.

У DOM-элементов в javascript есть свойства и атрибуты. И те и другие имеют имя и значение.
Поэтому иногда разработчики путают одно с другим.

Между ними есть соответствие, но оно не однозначное и его лучше понимать.

Свойства DOM-элементов

Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можно назначить свойство, используя обычный синтаксис.

var elem = document.getElementById('MyElement')
elem.mySuperProperty = 5

Значением свойства может быть любой объект. Это же javascript.

elem.master = {
  name: vasya
}
alert(elem.master.name)

DOM-Атрибуты

Теперь посмотрим на 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..

DOM-атрибуты VS DOM-свойства

Все, вроде бы, ясно. Есть свойства. Есть атрибуты.

Но создатели 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войство элемента и атрибут - это разные вещи. Не используйте одно вместо другого.

Вообще, обычно свойств хватает с головой.


Автор: Гость, дата: 14 июня, 2009 - 03:23

#permalink

В IE также является исключением ключевое атрибут for, для него используется свойство forHtml.

Атрибуту for тега <label> соответствует свойство htmlFor:

var label = document.createElement("label");
label.htmlFor = "inputID";
// и
label.setAttribute("for", "inputID");
Если когда-то нужен именно атрибут - напишите об этом в комментарии к этой статье.

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

var inputs = document.querySelectorAll('input[value*="text"]');


Автор: Куст (не зарегистрирован), дата: 29 июля, 2009 - 12:44

#permalink

Так и не понял что такое атрибут и свойство((((








Автор: Гость (не зарегистрирован), дата: 17 августа, 2009 - 11:12

#permalink

Отличная статья!
Я легко и быстро понял разницу.
Это именно то, что нужно.


Автор: Kolyaj, дата: 27 августа, 2009 - 22:15

#permalink

Тема IE не раскрыта, первый пример из раздела "Название атрибута не зависит от регистра" в ИЕ выведет как раз таки 1, а не 5.

Кто хочет раскрыть для себя особенности работы IE со свойствами и атрибутами, читать http://xpoint.ru/know-how/JavaScript/Atributyi?8


Автор: Гость (не зарегистрирован), дата: 16 октября, 2009 - 16:11

#permalink

У меня Windows 7 + IE 8

document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v'))  // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE

IE8 (сборка 7100) выдал не 5, как в примере, а undefined, как и firefox 3.5.3


Автор: Гость (не зарегистрирован), дата: 12 ноября, 2009 - 13:22

#permalink

Здравствуйте.
У меня для "левого" атрибута вывел значение SomeValue, а не undefined.
Это нормально?


Автор: Гость (не зарегистрирован), дата: 3 января, 2010 - 12:01

#permalink

да, там же сказано Для "левых" атрибутов браузер ничего не гарантирует... только я вот лично не догал что подразумевается под "левыми".. если "левый" == придуманный автором программы то почему он рботает в следующем же примере!?

document.body.abc = 1
document.body.ABC = 5
alert(document.body.abc) // => все еще 1

Автор: Леонид Розенблюм (не зарегистрирован), дата: 7 января, 2010 - 15:49

#permalink

В примере

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 преобразовал объект в строку?


Автор: Misha_White (не зарегистрирован), дата: 16 февраля, 2010 - 20:54

#permalink

Достаточно непонятно.... Sad

document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v'))  // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE

А если в FF написать alert(document.body.getAttribute('v').a) ? Мне кажется, что будет 5...


Автор: Максим Грач (не зарегистрирован), дата: 17 февраля, 2010 - 12:03

#permalink

А я столкнулся вот с чем:
В html есть, например, элемент

Данный пример не корректно работает в ИЕ (атрибут class="head" появляется, но не вступает в силу), зато работает во всех остальных браузерах:

var e = document.getElementById('title');
e.setAttribute('class', 'head');

результат:

<p id="title" class="head">

Зато в ИЕ работает следующий код:

var e = document.getElementById('title');
e.setAttribute('className', 'link');

результат в ИЕ:

<p id="title" class="head">

результат в остальных браузерах:

<p id="title" classname="head">

Автор: leha-bot (не зарегистрирован), дата: 5 марта, 2010 - 19:57

#permalink

В IE также является исключением ключевое атрибут for, для него используется свойство forHtml.

В IE в теге label используется for для того, чтобы обозначить id элемента формы, который будет давать этому элементу фокус (т.е., щелкните на галочке, и пунктиром выделится не только она, но и надпись label с этим свойством)


Автор: NarKoZ (не зарегистрирован), дата: 9 июня, 2010 - 11:27

#permalink

Надо поправить статью! А точнее подкоректировать коментарии...

Здесь:
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE

В первой строке атрибуту присвоено значение-объект. Firefox тут же автоматически преобразовал его в строку. А IE, в нарушение стандартов, оставил атрибут объектом.

Если так, то должно быть так?:
// "[object Object]" в IE
// 5 в Firefox


Автор: nd-studio (не зарегистрирован), дата: 15 августа, 2010 - 17:33

#permalink

NarKoZ, Вы не правы.
Как ранее написал BlueIce, "[object Object]" - это не указание на то, что перед нами объект, а лишь результат преобразования элемента в строку (читайте выше).
А вот строка
alert(document.body.getAttribute('v').a) // 5 в IE
как раз указывает на существование объекта document.body.getAttribute('v').a.


Автор: Читатель (не зарегистрирован), дата: 24 августа, 2010 - 11:09

#permalink

Не хватает конкретных примеров. Всё равно до конца не понятно отличие свойств и атрибутов. Что и в каких случаях лучше с точки зрения стандартов использовать: свойства или атрибуты? Например: id, class, style... Работает и через свойства, и через атрибуты. выше более-менее конкретно написал насчёт атрибутов. Это действительно так? И когда нужно применять не атрибуты, а свойства? Хотелось бы увидеть конкретные примеры, а не описание, в каких случаях они друг друга заменяют, а в каких нет.


Автор: Noise (не зарегистрирован), дата: 10 декабря, 2010 - 12:45

#permalink

Но создатели javascript решили (с лучшими намерениями) запутать ситуацию и создать искусственное соответствие между свойством и атрибутом.

По-моему разработчики javascript ничего не запутали. Запутывает скорее статья.


Автор: mxm (не зарегистрирован), дата: 6 января, 2011 - 21:15

#permalink

Немного "тупой" вопрос - если есть страница с примененными к ней CSS стилями, то, чтобы прочитать значение заданное стилем для тега (например: div {width: 400px}), надо использовать обращение к атрибутам (getAttribute(name))?


Автор: Гость (не зарегистрирован), дата: 16 января, 2011 - 17:42

#permalink

Вот этот пример, к слову, в IE8 выдаёт результат '1'.

document.body.setAttribute('abc', 1)
2
document.body.setAttribute('ABC', 5)
3
alert(document.body.getAttribute('abc')) // => стало 5

Может, потому что это не стандартное свойство? Или очередной косяк эксплорера?


Автор: Вопрашатель (не зарегистрирован), дата: 9 февраля, 2011 - 01:44

#permalink

А у меня такой вопрос-не совсем в тему.
Я желаю расширить функционал некоторых элементов,например Table и т.д.,добавив новые свойства и атрибуты.
Но известно,что Javscript и Dom-направление развиваются,изменяется,соответственно и интерпретатор Javascript Браузеров
Что если в следующей спецификации Javascript имя нового свойства какого-нибудь элемента будет совпадать с именем моего пользовательского атрибута или свойства?Тогда сайт будет некорректно работать?То есть в одно прекрасно утро мой сайт просто перестанет работать...А мне придется переделать кучу кода.(А я планирую сделать несколько "весомых" сайтов.
Как избежать такой проблемы?


Автор: Гость (не зарегистрирован), дата: 20 апреля, 2011 - 08:44

#permalink

Спасибо, толково расписал сложный вопрос!


Автор: Гость (не зарегистрирован), дата: 23 июня, 2011 - 18:13

#permalink

Ёмоё, ну правда, запутано
"Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можно назначить свойство, используя обычный синтаксис."
Смысл написанно: Узлы DOM являются объектами с точки зрения javascript. А у объектов есть свойства. Поэтому любому узлу можнозадать значение какого либо из имеющихся свойств, используя обычный синтаксис.
Я правильно понял?

P.S. Кстати таких логических ловушек (с неоднозначной трактовкой) много. Понятно дело усвоение материала страдает.


Автор: Гость (не зарегистрирован), дата: 23 июня, 2011 - 19:02

#permalink

Комментарий "Автор: Cy1on (не зарегистрирован), дата: 30 июля, 2009 - 15:20 " практически полностью расшифровывает всю путаницу в статье. Было бы прекрасно если б автор статьи "отрехтовал" статью (всю статью) со смыслом этого комментария. Или где либо (в логически обоснованном месте статьи) вставил данный комментарий полностью. От себя: возможно комментарий нужно доработать, например "Свойство - это атрибут узаконенный (закрепленный спецификацией, занесённый в спецификацию как неотъемлемое описание узла-элемента) с четко зафиксированным смыслом на который указывает названием (имя) данного свойства и возможными (а иногда фиксированными) значениями .... и т.д."


Автор: Гость (не зарегистрирован), дата: 29 июля, 2011 - 20:19

#permalink

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 выдает пустыми первые два окошка и пятерки в следующих двух. По-моему что-то не так)


Автор: garf (не зарегистрирован), дата: 10 августа, 2011 - 10:57

#permalink

Не понял, тут все перемешано насчет свойства и атрибута. Конкретно, что имеется ввиде под свойством и атрибутом?


Автор: RX200, дата: 6 сентября, 2011 - 19:19

#permalink

В FF столкнулся с такой вот проблемой:
Создаю программно(В скрипте) миню(XUL), В меню нужно выдилить строку, непрограмно это так выглядит

<menuitem label="Добавить" disabled="true"/>

Так вот, програмно создав минюшку, програмно добавляю этот атрибут, потом програмно меняю свойство disabled и всё(((( Больше через свойства доступа нет, выходит так что есть отдельно свойство и отдельно атрибут с одинаковыми именами. Всё дело в том что браузер не успел создать свойство, по подобию атрибута, а точнее несоздавал его, потому что он создаёт свойство только при визуализации меню.
Если например после создания менюшки в скрипте, я мышкой повожу на меню посмотрю его, а потом уже меняю свойство то всё работает так как мне надо, свойство и атрибуты скреплены) Но если я создам атрибут, а потом хоть что буду делать но непосмотрю визуально менюшку, и начну править свойство то создастся обсолютно независимое свойство. Конечно я могу программно просто править атрибуты, но мне интересно есть ли какой способ заставить браузер с помощью скрипта синхранизировать атрибуты и свойства??? и/или как напрямую привязать атрибут к свойству??


Автор: olga153b, дата: 18 сентября, 2011 - 14:29

#permalink

Атрибут - это строка (кроме IE)
Следующий код это наглядно демонстрирует:
document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE

скажите плз что означает VS

DOM-атрибуты VS DOM-свойства

и второй вопрос что означает "[object Object]"
где об этом написано?


Автор: Гость (не зарегистрирован), дата: 2 октября, 2011 - 08:25

#permalink

vs (иногда с точкой иногда без точки) сокращение от латинского слова versus (против). Так что Потап против Насти


Автор: Гость (не зарегистрирован), дата: 19 сентября, 2012 - 16:25

#permalink

а можно ли как нибудь узнать какие у элемента есть атрибуты (к примеру в виде массива)?


Автор: Гость (не зарегистрирован), дата: 22 сентября, 2012 - 18:49

#permalink

статья на мой взгляд не очень


Автор: Godson (не зарегистрирован), дата: 5 октября, 2012 - 22:40

#permalink

В сафари с айпада данный код работает иначе

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 так как оно было последним значением аттрибута.

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


Автор: romankrv, дата: 17 ноября, 2012 - 13:27

#permalink

Вот тут вы говорите чтобы отказаться от использования аттрибутов
Но как же dojo там одни аттрибуты

<div dojoType="dijit.form.Button" connectId="pool" data-dojo-props="onClick:setAttributes"></div>

и далее по списку

Вы чего серьезно отказаться решили


Автор: Гость (не зарегистрирован), дата: 15 февраля, 2013 - 14:51

#permalink

Почему все примеры "однобокие" и завязаны за дескриптором body? А если нужно получить или задать атрибуты у другого тэга


Автор: Гость (не зарегистрирован), дата: 18 апреля, 2013 - 10:17

#permalink

Молодец.


Автор: Гость (не зарегистрирован), дата: 2 сентября, 2013 - 09:46

#permalink

elem.mySuperProperty = 5
Это свойство. Как узнать, что это не атрибут?
Атрибуты можно назначать только через метод setAtribute?


Автор: Гость (не зарегистрирован), дата: 31 марта, 2014 - 23:23

#permalink

отличная статья , все четко и понятно


Автор: Гость (не зарегистрирован), дата: 23 октября, 2014 - 11:04

#permalink

Интересная статья. Вопрос: как поймать событие установки объекту атрибута. Например, disable для

? как через setAttributes, так и css.


Автор: Гость (не зарегистрирован), дата: 23 октября, 2014 - 11:06

#permalink

тэг < "div" > сожрал


Автор: pitonium (не зарегистрирован), дата: 19 мая, 2015 - 15:50

#permalink

Здравствуйте! Может я не в тему спрошу. Заранее извините. Как в document.body.setAttribute('abc', 1), вместо 'abc' подставить значение переменной. Например:

$name_attrib="id_elem";
document.body.setAttribute($name_attrib, 1);

Так не работает.


Автор: mee too (не зарегистрирован), дата: 1 октября, 2015 - 08:29

#permalink

>Автор: Бо (не зарегистрирован), дата: 20 октября, 2011 - 10:34 #permalink
>Статья, норм, автору зачот!
>Но если говорить откровенно, для того чтобы понять разницу между атрибутом и >свойством достаточно знать, что у объекта есть свойства а у тэга - атрибуты.
>Т.е. если рассматривать тэг то id это атрибут(как сказал бы автор:"Это же >HTML..."), а если рассматривать объект а DOM , то id это свойство (как сказал бы >автор: "Это же javascript...")

т.е. пока HTML нераспарсен (не преобразован) в DOM модель броузера:
HTML - состоит из тегов содержащих атрибуты,

после преобразования HTML в модель DOM - броузер содержит объекты со свойствами доступными через javascript.

т.е. свойства объектов DОМ модели заполняются (проецируются) из атрибутов тегов HTML.

т.к. атрибутов у тегов мало, то часть свойств объектов DOM заполняются по умолчанию или наследуются.


 
Текущий раздел
Поиск по сайту
Содержание

Дерево всех статей

Последние темы на форуме
Forum