getAttribute () a właściwości obiektu Element?


93

Wyrażenia lubią Element.getAttribute("id")i Element.idzwracają to samo.

Którego należy użyć, gdy potrzebujemy atrybutów obiektu HTMLElement?

Czy jest jakiś problem między przeglądarkami w przypadku tych metod, takich jak getAttribute()i setAttribute()?

Albo jakikolwiek wpływ na wydajność między bezpośrednim dostępem do właściwości obiektu a używaniem tych metod atrybutów?


Odpowiedzi:


127

getAttributepobiera atrybut elementu DOM, podczas gdy el.idpobiera właściwość tego elementu DOM. One nie są takie same.

W większości przypadków właściwości DOM są synchronizowane z atrybutami.

Jednak synchronizacja nie gwarantuje tej samej wartości . Klasycznym przykładem jest pomiędzy el.hrefi el.getAttribute('href')dla elementu kotwicy.

Na przykład:

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

Dzieje się tak, ponieważ zgodnie z W3C właściwość href musi być poprawnie sformułowanym łączem. Większość przeglądarek przestrzega tego standardu (zgadnij, kto tego nie robi?).

Jest to kolejny przypadek w input„s checkednieruchomości. Właściwość DOM zwraca truelub, falsepodczas gdy atrybut zwraca ciąg "checked"lub pusty ciąg.

Następnie są pewne właściwości, które są synchronizowane tylko w jedną stronę . Najlepszym przykładem jest valuewłasność inputelementu. Zmiana jego wartości przez właściwość DOM nie zmieni atrybutu (edytuj: sprawdź pierwszy komentarz, aby uzyskać większą precyzję).

Z tych powodów sugerowałbym dalsze używanie właściwości DOM , a nie atrybutów, ponieważ ich zachowanie jest różne w różnych przeglądarkach.

W rzeczywistości istnieją tylko dwa przypadki, w których musisz użyć atrybutów:

  1. Niestandardowy atrybut HTML, ponieważ nie jest synchronizowany z usługą DOM.
  2. Aby uzyskać dostęp do wbudowanego HTML atrybut, który nie jest zsynchronizowany z majątku, a na pewno trzeba atrybut (na przykład, oryginalny valuedanego inputelementu).

Jeśli chcesz uzyskać bardziej szczegółowe wyjaśnienie, zdecydowanie sugeruję przeczytanie tej strony . Zajmie Ci to tylko kilka minut, ale będziesz zachwycony informacjami (które tutaj podsumowałem).


9
+1 za ogólnie dobrą radę. Synchronizacja jest jednak valueniewielka : właściwość wejścia pobiera swoją początkową wartość z atrybutu, ale poza tym nie jest w ogóle z nim związana. valueAtrybut jest w pełni zsynchronizowane zamiast z defaultValuenieruchomości. Podobnie checkedi defaultChecked. Z wyjątkiem starego IE (<= 7 i późniejszych trybów zgodności), który zepsuł getAttribute()i setAttribute().
Tim Down

Dodałem swój komentarz jako „dalsze wyjaśnienie” :-)
Florian Margaine

2
Myślę, że pierwszy przykład jest zły. a.hrefzwraca pełny adres URL, a.getAttribute("href")zwraca atrybut dokładnie tak, jak defiend w źródle HTML.
Salman A

Jeśli próbujesz dowiedzieć się, czy wartość nie jest domyślna, lepiej jest użyć atrybutów. Wiele nowoczesnych przeglądarek zwraca wartość domyślną (np. input.formAction) Lub pusty ciąg znaków (np. a.download), Co powoduje, że są niejednoznaczne. Jedynym wyjątkiem są wartości, które nie są synchronizowane dwukierunkowo, takie jak value.
Kevin Li,

Jeśli id ​​nie jest w ogóle ustawiony w domenie, getAttribute zwróci wartość null, a element.id zwróci pusty ciąg. Czy to jest standard?
Maciej Krawczyk

11

getAttribute('attribute') zwykle zwraca wartość atrybutu jako ciąg znaków, dokładnie tak, jak zdefiniowano w źródle HTML strony.

Jednak element.attributemoże zwrócić znormalizowaną lub obliczoną wartość atrybutu. Przykłady:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href będzie zawierał pełny adres URL
  • <input type="checkbox" checked>
    • input.checked będzie true (boolean)
  • <input type="checkbox" checked="bleh">
    • input.checked będzie true (boolean)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width będzie wynosić 0 (liczba) przed załadowaniem obrazu
    • img.width wyniesie 64 (liczba) po załadowaniu obrazu (lub kilku jego pierwszych bajtów)
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img. szerokość będzie obliczoną 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img. szerokość będzie wynosić 50 (liczba)
  • <div style='background: lime;'></div>
    • div.style będzie obiektem

3

Zgodnie z tym testem jsPerf getAttribute jest wolniejszy niż idwłaściwość.

PS

Co dziwne, obie instrukcje działają bardzo źle w IE8 (w porównaniu z innymi przeglądarkami).


3

Zawsze używaj właściwości, chyba że masz konkretny powód, aby tego nie robić.

  • getAttribute()i setAttribute()są zepsute w starszym IE (i tryb zgodności w nowszych wersjach)
  • właściwości są wygodniejsze (w szczególności te odpowiadające atrybutom boolowskim)

Jest kilka wyjątków :

  • dostęp do atrybutów <form>elementów
  • dostęp do atrybutów niestandardowych (chociaż w ogóle odradzam używanie atrybutów niestandardowych)

O tym temacie pisałem kilka razy na SO:


Przed IE 8 właściwości i atrybuty były traktowane identycznie . Jak wspomniałeś wcześniej, nieruchomości są drogą do zrobienia.

@MattMcDonald: Tak, to jest złamanie, do którego nawiązywałem. Nie rozwinąłem tego w tej odpowiedzi, ponieważ czułem, że zrobiłem wystarczająco dużo w innych odpowiedziach, z którymi się łączyłem :)
Tim Down

3

.idzapisuje narzut wywołania funkcji. (co jest bardzo małe, ale pytałeś.)


Cześć gdoron, tak dla ciekawości: próbowałem znaleźć „oficjalne” wyjaśnienie tego (poza testem empirycznym, który jest wystarczająco jasny;)), ale bezskutecznie. Czy masz o tym jakiś link?
mamoo

0

Wypróbuj poniższy przykład, aby całkowicie to zrozumieć. Dla poniższego DIV

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

Element.getAttribute('class')Powróci myclassale trzeba użyć Element.classNamektóry pobiera go od nieruchomości DOM.


0

Jednym z obszarów, w którym ma to duże znaczenie, jest stylizacja CSS oparta na atrybutach.

Rozważ następujące:

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>

Element div z ustawioną bezpośrednio właściwością niestandardową nie odzwierciedla wartości atrybutu i nie jest wybierany przez nasz selektor atrybutu (div[custom] ) w css.

Jednak element div z atrybutem niestandardowym ustawionym za pomocą setAttributemożna wybrać za pomocą selektora atrybutu css i odpowiednio nadać mu styl.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.