У 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 (почему - см ниже)
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"
Вообще говоря, браузер не гарантирует синхронизацию атрибута и свойства.
onclick, не является функцией и не будет работать:
elem.setAttribute('onclick', 'alert(something)') // в IE не работает
Firefox корректно преобразовывает строку в функцию, поэтому там этот фрагмент работать будет. Но, вообще говоря, никакой браузер не обязан этого делать.
document.body.setAttribute('v',{a:5})
alert(document.body.getAttribute('v')) // "[object Object]" в Firefox
alert(document.body.getAttribute('v').a) // 5 в IE
В первой строке атрибуту присвоено значение-объект. Firefox тут же автоматически преобразовал его в строку. А IE, в нарушение стандартов, оставил атрибут объектом.
classNameclass соответствует свойство className. Так получилось из-за того, что class является зарезервированным словом javascript.В IE также является исключением атрибут for, для него используется свойство forHtml.
Cвойство элемента и атрибут - это разные вещи. Не используйте одно вместо другого.
Вообще, обычно свойств хватает с головой.