getAttribute () против свойств объекта Element?


93

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

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

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

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


1
Аналогичный вопрос: Свойства и атрибуты в HTML
sleske

Ответы:


127

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«S checkedсобственности. Свойство DOM возвращает trueили в falseто время как атрибут возвращает строку "checked"или пустую строку.

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

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

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

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

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


9
+1 за вообще хороший совет. Однако с синхронизацией дело обстоит не так: valueсвойство входа получает свое начальное значение из атрибута, но в остальном вообще не привязано к нему. valueАтрибут полностью синхронизирован вместо с defaultValueсобственностью. Точно так же checkedи defaultChecked. За исключением старого IE (<= 7 и режимы совместимости позже), в котором были сломаны getAttribute()и setAttribute().
Тим Даун

Добавил ваш комментарий как «дальнейшее объяснение» :-)
Florian Margaine

2
Я думаю, вы ошиблись в первом примере. a.hrefвозвращает полный URL, a.getAttribute("href")возвращает атрибут точно так же, как defiend в исходном HTML.
Salman A

Если вы пытаетесь выяснить, не является ли значение значением по умолчанию, вам лучше использовать атрибуты. Многие современные браузеры возвращают значение по умолчанию (например input.formAction) или пустую строку (например a.download), что делает ситуацию неоднозначной. Единственным исключением являются значения, которые не синхронизируются с двусторонней синхронизацией, например value.
Кевин Ли

Если id вообще не установлен в dom, getAttribute вернет null, а element.id вернет пустую строку. Это стандарт?
Maciej Krawczyk

11

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

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

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href будет содержать полный URL
  • <input type="checkbox" checked>
    • input.checked будет истинным (логическим)
  • <input type="checkbox" checked="bleh">
    • input.checked будет истинным (логическим)
  • <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

Согласно этому тесту jsPerf getAttribute медленнее, чем idсвойство.

PS

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


3

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

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

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

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

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


До IE 8 свойства и атрибуты обрабатывались одинаково . Как вы упоминали ранее, недвижимость - это лучший способ.

@MattMcDonald: Да, это та поломка, о которой я говорил. Я не стал подробно рассказывать об этом в этом ответе, потому что чувствовал, что сделал достаточно в других ответах, на которые я ссылался :)
Тим Даун

3

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


Привет, gdoron, просто из любопытства: я пытался найти «официальное» объяснение этому (помимо эмпирического теста, который достаточно ясен;)), но безуспешно. У вас есть ссылка на это?
mamoo

0

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

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

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


0

Одна из областей, где это имеет большое значение, - это стили 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>

Div с настраиваемым набором свойств напрямую не отражает значение атрибута и не выбирается нашим селектором атрибутов ( div[custom]) в CSS.

Однако div с настраиваемым атрибутом, установленным с помощью setAttribute, можно выбрать с помощью селектора атрибутов css и соответствующим образом оформить.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.