GetAttribute() и свойства объекта Element?

Выражения типа Element.getAttribute("id") и Element.id возвращают одно и то же.

Какой из них следует использовать, когда нам нужны атрибуты объекта HTMLElement?

Есть ли проблема с перекрестным браузером с такими методами, как getAttribute() и setAttribute()?

Или любое влияние на производительность между прямым доступом к свойствам объекта и использованием этих методов атрибутов?

Ответ 1

getAttribute извлекает атрибут элемента DOM, а el.id извлекает свойство этого элемента DOM. Они не совпадают.

В большинстве случаев свойства DOM синхронизируются с атрибутами.

Однако синхронизация не гарантирует одно и то же значение. Классический пример - между el.href и el.getAttribute('href') для привязывающего элемента.

Например:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Это происходит потому, что в соответствии с W3C свойство href должно быть хорошо сформированной ссылкой. Большинство браузеров уважают этот стандарт (угадайте, кто нет?).

Существует еще один случай для свойства input checked. Свойство DOM возвращает true или false, в то время как атрибут возвращает строку "checked" или пустую строку.

И тогда есть некоторые свойства, которые синхронизированы только в одну сторону. Лучшим примером является свойство value элемента input. Изменение его значения с помощью свойства DOM не изменит атрибут (отредактируйте: проверьте первый комментарий для большей точности).

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

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

  • Пользовательский атрибут HTML, поскольку он не синхронизирован с свойством DOM.
  • Чтобы получить доступ к встроенному атрибуту HTML, который не синхронизирован с этим свойством, и вы уверены, что вам нужен атрибут (например, оригинальный value элемента input).

Если вы хотите получить более подробное объяснение, я настоятельно рекомендую вам прочитать эту страницу. Это займет у вас всего несколько минут, но вы будете в восторге от информации (которую я подытожил здесь).

Ответ 2

getAttribute('attribute') обычно возвращает значение атрибута в виде строки, точно так же, как определено в источнике HTML страницы.

Однако element.attribute может возвращать нормализованное или вычисленное значение атрибута. Примеры:

  • <a href="/foo"></a>
    • a.href будет содержать полный URL
  • <input type="checkbox" checked>
    • input.checked будет true (boolean)
  • <input type="checkbox" checked="bleh">
    • input.checked будет true (boolean)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width будет 0 (число) до загрузки изображения
    • img.width будет 64 (число), когда загружается изображение (или первые несколько его байтов)
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width будет рассчитан 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width будет 50 (число)
  • <div style='background: lime;'></div>
    • div.style будет объектом

Ответ 3

.id сохраняет служебные данные функции. (что очень мало, но вы спросили.)

Ответ 4

В соответствии с этот тест jsPerf getAttribute медленнее, чем свойство id.

PS

Как ни странно, оба оператора очень плохо работают на IE8 (по сравнению с другими браузерами).

Ответ 5

Всегда используйте свойства, если у вас нет конкретной причины.

  • getAttribute() и setAttribute() разбиты в более старом IE (и режиме совместимости в более поздних версиях).
  • свойства более удобны (в частности, те, которые соответствуют логическим атрибутам)

Есть некоторые исключения:

  • доступ к атрибутам элементов <form>
  • доступ к пользовательским атрибутам (хотя я вообще не буду использовать пользовательские атрибуты)

Я писал об этой теме несколько раз на SO:

Ответ 6

Попробуйте привести пример, чтобы понять это полностью. Для ниже DIV

<div class="myclass"></div>

Element.getAttribute('class') вернет myclass, но вы должны использовать Element.className, который извлекает его из свойства DOM.

Ответ 7

Одна из областей, где это имеет большое значение, - это стиль css, основанный на атрибутах.

Рассмотрим следующее:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>