Jaka jest różnica między właściwościami a atrybutami w HTML?

407

Po zmianach wprowadzonych w jQuery 1.6.1 starałem się zdefiniować różnicę między właściwościami a atrybutami w HTML.

Patrząc na listę w informacjach o wersji jQuery 1.6.1 (u dołu), można klasyfikować właściwości i atrybuty HTML w następujący sposób:

  • Właściwości: Wszystkie, które albo mają wartość logiczną, albo są obliczone na podstawie UA, takie jak selectedIndex.

  • Atrybuty: „Atrybuty”, które można dodać do elementu HTML, który nie jest wartością logiczną ani nie zawiera wartości wygenerowanej przez UA.

Myśli?

schalkneethling
źródło
6
Możliwy duplikat .prop () vs .attr ()
Naftali alias Neal

Odpowiedzi:

825

Podczas pisania kodu źródłowego HTML możesz definiować atrybuty elementów HTML. Następnie, gdy przeglądarka przeanalizuje kod, zostanie utworzony odpowiedni węzeł DOM. Ten węzeł jest obiektem, a zatem ma właściwości .

Na przykład ten element HTML:

<input type="text" value="Name:">

ma 2 atrybuty ( typei value).

Gdy przeglądarka przeanalizuje ten kod, zostanie utworzony obiekt HTMLInputElement , który będzie zawierał dziesiątki właściwości, takich jak: accept, accessKey, align, alt, atrybuty, autofocus, baseURI, zaznaczone, childElementCount, childNodes, child, classList, className, clientHeight itp.

Dla danego obiektu węzła DOM właściwości są właściwościami tego obiektu, a atrybuty są elementami attributeswłaściwości tego obiektu.

Kiedy węzeł DOM jest tworzony dla danego elementu HTML, wiele jego właściwości odnosi się do atrybutów o takich samych lub podobnych nazwach, ale nie jest to relacja jeden do jednego. Na przykład dla tego elementu HTML:

<input id="the-input" type="text" value="Name:">

DOM odpowiedni węzeł będzie mieć id, typei valuewłaściwości (między innymi):

  • idNieruchomość jest odzwierciedlone nieruchomość dla idatrybutu: Pierwsze właściwość odczytuje wartość atrybutu, a ustawienie właściwości zapisuje wartość atrybutu. idjest czysto odzwierciedloną właściwością, nie modyfikuje ani nie ogranicza wartości.

  • typeNieruchomość jest odzwierciedlone nieruchomość dla typeatrybutu: Pierwsze właściwość odczytuje wartość atrybutu, a ustawienie właściwości zapisuje wartość atrybutu. typenie jest czystą odzwierciedloną właściwością, ponieważ ogranicza się do znanych wartości (np. prawidłowych typów danych wejściowych). Jeśli tak <input type="foo">, to theInput.getAttribute("type")daje, "foo"ale theInput.typedaje "text".

  • Natomiast valuewłaściwość nie odzwierciedla valueatrybutu. Zamiast tego jest to bieżąca wartość wejścia. Gdy użytkownik ręcznie zmieni wartość pola wprowadzania, valuewłaściwość odzwierciedli tę zmianę. Jeśli więc użytkownik wprowadzi dane "John"w polu wprowadzania, wówczas:

    theInput.value // returns "John"

    natomiast:

    theInput.getAttribute('value') // returns "Name:"

    valueNieruchomość odzwierciedla aktualny tekst-zawartość wewnątrz pola wejściowego, natomiast valueatrybut zawiera początkowy tekst-zawartość valueatrybutu z kodu źródłowego HTML.

    Więc jeśli chcesz wiedzieć, co aktualnie znajduje się w polu tekstowym, przeczytaj właściwość. Jeśli jednak chcesz wiedzieć, jaka była początkowa wartość pola tekstowego, przeczytaj atrybut. Lub możesz użyć defaultValuewłaściwości, która jest czystym odzwierciedleniem valueatrybutu:

    theInput.value                 // returns "John"
    theInput.getAttribute('value') // returns "Name:"
    theInput.defaultValue          // returns "Name:"

Istnieje kilka właściwości, które bezpośrednio odzwierciedlają ich atrybut ( rel, id), niektóre są bezpośrednimi odbicia z nieznacznie różnymi nazwami ( htmlForodzwierciedla forcechę, classNameodzwierciedla classatrybut), wielu, które odzwierciedlają ich atrybut ale z ograniczeniami / modyfikacjami ( src, href, disabled, multiple), a więc na. Specyfikacja obejmuje różne rodzaje odbić.

Šime Vidas
źródło
1
Hej Sime, domyślam się, że jest to dość niejednoznaczne, szczególnie jeśli spojrzysz tutaj: w3.org/TR/html4/index/attributes.html , i nie ma jednoznacznej odpowiedzi. Zasadniczo należy postępować zgodnie z tym, co podano w podsumowaniu na blogu jQuery, a nawet wtedy jeden
mapuje
4
@oss Twój link odnosi się do listy atrybutów HTML. Ta lista nie jest dwuznaczna - to atrybuty.
Šime Vidas
czy są jakieś dokumenty dotyczące relacji? @ ŠimeVidas
SKing7,
3
Gdzie mogę znaleźć pełną listę atrybutów właściwości (jak for-> htmlFor) i podobnie listę właściwości, które pobierają swoją wartość początkową z atrybutu, ale go nie odzwierciedlają ( input.value). Spodziewam się, że będzie to gdzieś w bibliotece takiej jak github.com/Matt-Esch/virtual-dom, ale tak naprawdę nie jest to udokumentowane.
sstur
1
@Pim Sam tego nie czytałem, ale ta 4-częściowa seria artykułów wydaje się świetnym źródłem: twitter.com/addyosmani/status/1082177515618295808
Šime Vidas
53

Po przeczytaniu odpowiedzi Sime'a Vidasa przeszukałem więcej i znalazłem bardzo proste i łatwe do zrozumienia wyjaśnienie w dokumentach kątowych .

Atrybut HTML a właściwość DOM


Atrybuty są definiowane przez HTML. Właściwości są zdefiniowane przez DOM (Document Object Model).

  • Kilka atrybutów HTML ma mapowanie 1: 1 na właściwości. idjest jednym przykładem.

  • Niektóre atrybuty HTML nie mają odpowiednich właściwości. colspanjest jednym przykładem.

  • Niektóre właściwości DOM nie mają odpowiednich atrybutów. textContent jest jednym przykładem.

  • Wiele atrybutów HTML wydaje się mapować na właściwości ... ale nie w taki sposób, jak mogłoby się wydawać!

Ta ostatnia kategoria jest myląca, dopóki nie zrozumiesz tej ogólnej zasady:

Atrybuty inicjują właściwości DOM, a następnie są wykonywane. Wartości właściwości mogą ulec zmianie; wartości atrybutów nie mogą.

Na przykład, gdy przeglądarka renderuje <input type="text" value="Bob">, tworzy odpowiedni węzeł DOM z valuewłaściwością zainicjowaną na „Bob”.

Gdy użytkownik wprowadza „Sally” w polu wprowadzania, value właściwość elementu DOM zmienia się w „Sally”. Ale value atrybut HTML pozostaje niezmieniony, gdy odkrywasz, że pytasz element wejściowy o ten atrybut: input.getAttribute('value')zwraca „Bob”.

Atrybut HTML valueokreśla wartość początkową ; value właściwość DOM jest bieżącą wartością.


Ten disabledatrybut jest kolejnym osobliwym przykładem. disabledWłaściwość przycisku jest falsedomyślnie, więc przycisk jest włączony. Po dodaniu disabledatrybutu sama jego obecność inicjuje właściwość przycisku, disabledaby trueprzycisk był wyłączony.

Dodanie i usunięcie disabledatrybutu wyłącza i włącza przycisk. Wartość atrybutu jest nieistotna, dlatego nie można włączyć przycisku pisząc<button disabled="false">Still Disabled</button>.

Ustawianie przycisku na disabled własność wyłącza lub włącza przycisk. Wartość nieruchomości ma znaczenie.

Atrybut HTML i właściwość DOM nie są tym samym, nawet jeśli mają tę samą nazwę.

subtleseeker
źródło
Ten przykład jest niewłaściwy: colspanatrybut ma colSpanwłaściwość. ... Więc który atrybut nie ma teraz powiązanej właściwości?
Robert Siemer
46

Odpowiedzi już wyjaśniają, w jaki sposób atrybuty i właściwości są traktowane w różny sposób, ale naprawdę chciałbym wskazać, jak całkowicie jest to szalone . Nawet jeśli jest to do pewnego stopnia specyfikacja.

Szaleństwem jest mieć niektóre atrybuty (np. Id, klasa, foo, bar ), aby zachować tylko jeden rodzaj wartości w DOM, a niektóre atrybuty (np. Zaznaczone, wybrane ), aby zachować dwie wartości; to znaczy wartość „kiedy został załadowany” i wartość „stanu dynamicznego”. (Czy DOM nie powinien reprezentować stanu dokumentu w pełnym zakresie?)

Jest absolutnie konieczne, aby dwa pola wprowadzania , np. Tekst i pole wyboru, zachowywały się w ten sam sposób . Jeśli pole wprowadzania tekstu nie zachowuje oddzielnej wartości „po załadowaniu” i wartości „bieżącej, dynamicznej”, dlaczego pole wyboru jest zaznaczone? Jeśli pole wyboru ma dwie wartości dla sprawdzonego atrybutu, dlaczego nie ma dwóch dla jego atrybutów klasy i identyfikatora ? Jeśli spodziewasz się zmienić wartość pola tekstowego * input * i oczekujesz, że DOM (tj. „Reprezentacja szeregowa”) zmieni się i odzwierciedli tę zmianę, dlaczego, u licha, nie spodziewałbyś się tego samego z pola wejściowego wpisz pole wyboru na zaznaczonym atrybucie?

Rozróżnienie „to atrybut boolowski” po prostu nie ma dla mnie żadnego sensu lub przynajmniej nie jest wystarczającym powodem.

sibidiba
źródło
21
To nie jest odpowiedź, ale zgadzam się z tobą; to jest całkowicie szalone.
Samuel
Tak, ta koncepcja jest do bani i nie powinna być tak źle standaryzowana. Był to jeden z przypadków (jak na przykład innerHTML), który był dobry w starej IE i powinien zostać przyjęty przez standardy. Tam, gdzie to możliwe, właściwości i atrybuty były synchronizowane, nawet atrybuty niestandardowe, dzięki czemu składnia js dot była bardzo czytelna. HTML5 sprawia, że ​​niestandardowe tagi HTML są pierwszorzędnymi obywatelami, niestandardowe atrybuty również powinny być. Ta funkcja jest usuwana, ponieważ stary IE wciąż stanowi poważny problem - dopiero teraz widzimy, że wiele korporacji tradycyjnie utknęło w IE dla starych systemów, które teraz uważają je za uszkodzone w IE10.
Mike Nelson
48
To nie jest szalone. Źle zrozumiałeś. checkedAtrybut jest reprezentowany przez defaultCheckedobiekcie (podobnie do wprowadzania tekstu w pionie valuecechą jest reprezentowany przez defaultValuewłasności). Druga właściwość, checkedjest wymagana do reprezentowania, czy pole wyboru jest zaznaczone, ponieważ jest to nieodłączna część funkcjonalności pola wyboru: jest interaktywne i może zostać zmienione (i zresetowane do domyślnego, jeśli obecny jest przycisk resetowania formularza) , w sposób, w jaki inny atrybut taki jak idnie jest. Nie ma to nic wspólnego z faktem, że jest to atrybut logiczny.
Tim Down
3
@TimDown - Dzięki. To faktycznie doprowadziło mnie do WTF? garb.
pedz
12
@TimDown Nadal uważam, że jest „szalony”, ponieważ każde logiczne podejście spowodowałoby, że nazwa właściwości i nazwa atrybutu byłyby zgodne, lub przynajmniej nie miałaby identycznej nazwy atrybutu i nazwy właściwości, które nie są powiązane (tzn. Sprawdzony atrybut odnosi się do wartości domyślnej Sprawdzone właściwość, podczas gdy sprawdzona właściwość nie jest powiązana). W rzeczywistości logiczne podejście, które wszyscy zakładają, ma miejsce na początku, polegałoby na tym, aby w ogóle nie rozdzielać atrybutów i właściwości. Atrybuty nie powinny być niezmienne, ale zawsze powinny odzwierciedlać wartości właściwości. Nie powinno być rozróżnienia między nimi.
dallin,
10

cóż, są one określone przez w3c, co jest atrybutem, a co właściwością http://www.w3.org/TR/SVGTiny12/attributeTable.html

ale obecnie attr i prop nie są tak różne i są prawie takie same

ale wolą rekwizyty do niektórych rzeczy

Podsumowanie preferowanego użycia

Metodę .prop () należy stosować dla atrybutów / właściwości boolowskich oraz dla właściwości, które nie istnieją w html (takich jak window.location). Wszystkie pozostałe atrybuty (te, które można zobaczyć w html) mogą i powinny być nadal przetwarzane za pomocą metody .attr ().

no cóż, właściwie nie musisz niczego zmieniać, jeśli używasz attr lub prop albo oba, oba działają, ale widziałem we własnej aplikacji, że prop działał tam, gdzie atrr nie zrobił, więc wziąłem moją aplikację w wersji 1.6 =)

Daniel Ruf
źródło
Hej Daniel, przeczytałem to. Wygląda na to, że znana jest wyraźna definicja rozcięcia, która rozdziela te dwa elementy, ponieważ niektóre z elementów wymienionych poniżej Sime można również dodać do elementu HTML, na przykład alt. Będzie nadal czytał niektóre specyfikacje HTML i sprawdził, czy rzeczywiście istnieje sposób na wyraźne rozróżnienie tych dwóch w praktyce.
schalkneethling
3
Ten dokument dotyczy SVG, a nie HTML.
Luzado,
5

Różnica właściwości i atrybutów HTML:

Najpierw spójrzmy na definicje tych słów, zanim ocenimy, jaka jest różnica w HTML:

Angielska definicja:

  • Atrybuty odnoszą się do dodatkowych informacji o obiekcie.
  • Właściwości opisują cechy obiektu.

W kontekście HTML:

Kiedy przeglądarka analizuje HTML, tworzy drzewiastą strukturę danych, która w zasadzie jest reprezentacją HTML w pamięci. Struktura danych drzewa zawiera węzły, które są elementami HTML i tekstem. Związane z tym atrybuty i właściwości są następujące:

  • Atrybuty to dodatkowe informacje, które możemy umieścić w kodzie HTML w celu zainicjowania niektórych właściwości DOM.
  • Właściwości są tworzone, gdy przeglądarka analizuje kod HTML i generuje DOM. Każdy element w DOM ma swój własny zestaw właściwości, które wszystkie są ustawione przez przeglądarkę. Niektóre z tych właściwości mogą mieć ustawioną wartość początkową za pomocą atrybutów HTML. Za każdym razem, gdy zmienia się właściwość DOM, która ma wpływ na renderowaną stronę, strona zostanie natychmiast ponownie renderowana

Ważne jest również, aby zdawać sobie sprawę, że mapowanie tych właściwości nie jest równe 1 do 1. Innymi słowy, nie każdy atrybut, który podajemy w elemencie HTML, będzie miał podobną nazwę DOM.

Ponadto mają różne elementy DOM różne właściwości. Na przykład <input>element ma właściwość wartości, która nie jest obecna we <div>właściwości.

Przykład:

Weźmy następujący dokument HTML:

 <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">  <!-- charset is a attribute -->
  <meta name="viewport" content="width=device-width"> <!-- name and content are attributes -->
  <title>JS Bin</title>
</head>
<body>
<div id="foo" class="bar foobar">hi</div> <!-- id and class are attributes -->
</body>
</html>

Następnie sprawdzamy <div>w konsoli JS:

 console.dir(document.getElementById('foo'));

Widzimy następujące właściwości DOM (chrome devtools, nie wszystkie właściwości pokazane):

właściwości i atrybuty HTML

  • Widzimy, że identyfikator atrybutu w HTML jest teraz także właściwością id w DOM. Identyfikator został zainicjowany przez HTML (chociaż możemy to zmienić za pomocą javascript).
  • Widzimy, że atrybut class w HTML nie ma odpowiedniej właściwości class ( classjest zarezerwowanym słowem kluczowym w JS). Ale właściwie 2 właściwości classListi className.
Willem van der Veen
źródło