Czy opracowano najlepszą praktykę dotyczącą używania setAttribute
zamiast .
notacji atrybutu dot ( )?
Na przykład:
myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");
lub
myObj.className = "nameOfClass";
myObj.id = "someID";
javascript
attributes
setattribute
Franciszek
źródło
źródło
.setAttribute()
celu[key] = value
, wszystko zaczęło się w magiczny sposób działa.Odpowiedzi:
Powinieneś zawsze używać bezpośredniego
.attribute
formularza (ale zobacz link quirksmode poniżej), jeśli chcesz mieć programowy dostęp w JavaScript. Powinien poprawnie obsługiwać różne typy atrybutów (myśl „onload”).Użyj
getAttribute
/,setAttribute
jeśli chcesz poradzić sobie z DOM takim, jakim jest (np. Tylko dosłowny tekst). Różne przeglądarki mylą te dwa. Zobacz Tryby dziwactwa: zgodność atrybutów (nie) .źródło
Od Javascript: The Definitive Guide , wyjaśnia wszystko. Zauważa, że obiekty HTMLElement dokumentu HTML definiują właściwości JS, które odpowiadają wszystkim standardowym atrybutom HTML.
Musisz więc użyć tylko
setAttribute
w przypadku niestandardowych atrybutów.Przykład:
źródło
node.frameborder
NIE jest zdefiniowany, więc musisz uzyskaćAtrybut, aby odzyskać wartość.frameBorder
bezpośrednio, ale zwróć uwagę na wielkie litery. Ktoś pomyślał, że to dobry pomysł na wielbłądzieZamów JavaScript w odpowiednikach atrybutów HTML. Nie udało mi się znaleźć żadnej specyfikacji tego, ale wydaje się, że sieć zgadza się, że jest to kwestia 12 konkretnych przypadków (przynajmniej dla HTML 4). Zobacz na przykład następujący post: drupal.org/node/1420706#comment-6423420usemap
Atrybut nie można ustawić za pomocą notacji kropki przy tworzeniu mapy dynamicznie na obrazie. Wymagaimg.setAttribute('usemap', "#MapName");
Czy Twoja odpowiedź sugeruje, żeusemap
jest to zatem „niestandardowe”?Żadna z poprzednich odpowiedzi nie jest kompletna, a większość zawiera błędne informacje.
Istnieją trzy sposoby uzyskania dostępu do atrybutów elementu DOM w JavaScript. Wszystkie trzy działają niezawodnie w nowoczesnych przeglądarkach, o ile wiesz, jak z nich korzystać.
1.
element.attributes
Elementy mają właściwość atrybuty , które zwraca na żywo NamedNodeMap z Attr obiektów. Indeksy tej kolekcji mogą się różnić w zależności od przeglądarki. Zatem zamówienie nie jest gwarantowane.
NamedNodeMap
ma metody dodawania i usuwania atrybutów (getNamedItem
isetNamedItem
odpowiednio).Zwróć uwagę, że chociaż w XML rozróżniana jest wielkość liter, specyfikacja DOM wymaga znormalizowania nazw ciągów , więc w nazwach przekazywanych
getNamedItem
faktycznie nie jest rozróżniana wielkość liter.Przykładowe użycie:
2.
element.getAttribute
ielement.setAttribute
Te metody istnieją bezpośrednio,
Element
bez potrzeby uzyskiwania dostępuattributes
i ich metod, ale wykonują te same funkcje.Ponownie zauważ, że w nazwach łańcuchów nie rozróżniana jest wielkość liter.
Przykładowe użycie:
3. Właściwości obiektu DOM, takie jak
element.id
Dostęp do wielu atrybutów można uzyskać za pomocą wygodnych właściwości obiektu DOM. To, które atrybuty istnieją, zależy od typu węzła DOM, a nie które atrybuty są zdefiniowane w kodzie HTML. Właściwości są zdefiniowane gdzieś w łańcuchu prototypowym przedmiotowego obiektu DOM. Określone określone właściwości będą zależeć od typu elementu, do którego uzyskujesz dostęp. Na przykład,
className
iid
są zdefiniowaneElement
i istnieje na wszystkich węzłach DOM, które elementy (tj. Nie tekstowe lub komentarz węzły). Alevalue
jest bardziej wąski. Jest zdefiniowanyHTMLInputElement
i może nie istnieć w innych elementach.Zauważ, że we właściwościach JavaScript rozróżniana jest wielkość liter. Chociaż większość właściwości będzie używać małych liter, niektóre z nich to camelCase. Dlatego zawsze należy sprawdzić specyfikację, aby się upewnić.
Ten „wykres” przechwytuje część łańcucha prototypów dla tych obiektów DOM. Nie jest nawet blisko ukończenia, ale oddaje ogólną strukturę.
Przykładowe użycie:
Zastrzeżenie: jest to wyjaśnienie, w jaki sposób określa specyfikację HTML, a nowoczesne przeglądarki obsługują atrybuty. Nie próbowałem radzić sobie z ograniczeniami starożytnych, zepsutych przeglądarek. Jeśli potrzebujesz obsługiwać stare przeglądarki, oprócz tych informacji musisz wiedzieć, co jest zepsute w tych przeglądarkach.
źródło
Jeden przypadek, który uznałem za
setAttribute
niezbędny, to zmiana atrybutów ARIA, ponieważ nie ma odpowiednich właściwości. Na przykładNie ma
x.arialabel
nic takiego, więc musisz użyć setAttribute.Edycja: x [„aria-label”] nie działa . Naprawdę potrzebujesz setAttribute.
źródło
Te odpowiedzi nie są odpowiedzią na duże zamieszanie między właściwościami a atrybutami . Ponadto, w zależności od prototypu Javascript, czasami można użyć właściwości elementu, aby uzyskać dostęp do atrybutów, a czasem nie.
Najpierw musisz pamiętać, że an
HTMLElement
jest obiektem Javascript. Podobnie jak wszystkie obiekty mają właściwości. Jasne, możesz utworzyć właściwość o nazwie prawie wszystko, co chcesz w środkuHTMLElement
, ale nie musi ona nic robić z DOM (co jest na stronie). Notacja kropkowa (.
) dotyczy właściwości . Teraz istnieją pewne specjalne właściwości, które są mapowane na atrybuty, a w tym czasie lub podczas pisania są tylko 4, które są gwarantowane (więcej na ten temat później).Wszystkie
HTMLElement
s zawierają właściwość o nazwieattributes
.HTMLElement.attributes
to obiekt na żywo,NamedNodeMap
który odnosi się do elementów w DOM. „Na żywo” oznacza, że gdy węzeł zmienia się w DOM, zmieniają się po stronie JavaScript i odwrotnie. W tym przypadku atrybutami DOM są omawiane węzły. ANode
ma.nodeValue
właściwość, którą możesz zmienić.NamedNodeMap
obiekty mają funkcję o nazwie, wsetNamedItem
której można zmienić cały węzeł. Możesz także uzyskać bezpośredni dostęp do węzła za pomocą klucza. Na przykład możesz powiedzieć,.attributes["dir"]
który jest taki sam jak.attributes.getNamedItem('dir');
(Uwaga boczna,NamedNodeMap
nie rozróżnia wielkości liter, więc możesz również przekazać'DIR'
);Istnieje podobna funkcja bezpośrednio, w
HTMLElement
której możesz po prostu wywołać,setAttribute
która automatycznie utworzy węzeł, jeśli nie istnieje i ustawinodeValue
. Istnieją również niektóre atrybuty, do których można uzyskać bezpośredni dostęp jako właściwościHTMLElement
za pośrednictwem specjalnych właściwości , takich jakdir
. Oto przybliżone odwzorowanie tego, jak to wygląda:Możesz więc zmienić
dir
atrybuty na 6 sposobów:Można zaktualizować wszystkie właściwości z metodami # 1-5, ale tylko
dir
,id
,lang
, iclassName
metodą # 6.Rozszerzenia HTMLElement
HTMLElement
ma te 4 specjalne właściwości. Niektóre elementy są rozszerzonymi klasami oHTMLElement
jeszcze większej liczbie odwzorowanych właściwości. Na przykład,HTMLAnchorElement
maHTMLAnchorElement.href
,HTMLAnchorElement.rel
iHTMLAnchorElement.target
. Ale uwaga : jeśli ustawisz te właściwości na elementach, które nie mają tych specjalnych właściwości (jak na aHTMLTableElement
), wówczas atrybuty nie zostaną zmienione i będą to zwykłe niestandardowe właściwości. Aby lepiej zrozumieć, oto przykład jego dziedziczenia:Właściwości niestandardowe
Teraz wielkie ostrzeżenie: Jak wszystkie obiekty JavaScript , możesz dodawać własne właściwości. Ale to nic nie zmieni w DOM. Możesz to zrobić:
Ale to to samo co
Oznacza to, że dodanie niestandardowej właściwości nie zostanie połączone
.attributes[attr].nodeValue
.Występ
Zbudowałem skrzynkę testową jsperf, aby pokazać różnicę: https://jsperf.com/set-attribute-comparison . Zasadniczo w celu:
dir
,id
,className
).element.attributes.ATTRIBUTENAME.nodeValue =
element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
element.attributes.ATTRIBUTENAME = newNode
element.attributes.setNamedItem(ATTRIBUTENAME) = newNode
Wniosek (TL; DR)
Za pomocą specjalnych mapowania własności z
HTMLElement
:element.dir
,element.id
,element.className
, lubelement.lang
.Jeśli masz 100% pewności, że element jest rozszerzeniem
HTMLElement
o specjalnej właściwości, użyj tego specjalnego odwzorowania. (Możesz to sprawdzić za pomocąif (element instanceof HTMLAnchorElement)
).Jeśli masz 100% pewności, że atrybut już istnieje, użyj
element.attributes.ATTRIBUTENAME.nodeValue = newValue
.Jeśli nie, użyj
setAttribute()
.źródło
classList
istnieje 100% gwarancji, że istnieje, ale nie jest to ciąg znaków, toDOMTokenList
obiekt na żywo ..className
Bezpośrednie ustawienie jest szybsze niż manipulowanieclassList
, ale nadpisujesz całość..value
, zmieniasz wartość wewnętrznąHTMLInputElement
, która jest następnie odzwierciedlana w atrybutach. Nie muszą tak byćstring
..valueAsNumber
zmieni sięvalue
wewnętrznie , a jegostring
forma pojawi się wvalue
atrybucie. developer.mozilla.org/en-US/docs/Web/HTML/Attributes„Kiedy używać setAttribute vs .attribute = w JavaScript?”
Ogólną zasadą jest używanie
.attribute
i sprawdzanie, czy działa w przeglądarce...Jeśli działa w przeglądarce, możesz zacząć.
..If nie, użyj
.setAttribute(attribute, value)
zamiast.attribute
za które atrybutu.Powtórz płukanie dla wszystkich atrybutów.
Cóż, jeśli jesteś leniwy, możesz po prostu użyć
.setAttribute
. To powinno działać dobrze w większości przeglądarek. (Chociaż obsługiwane przeglądarki.attribute
mogą to zoptymalizować lepiej niż.setAttribute(attribute, value)
.)źródło
Wygląda to na jeden przypadek, w którym lepiej jest użyć setAttribute:
Dev.Opera - Wydajny JavaScript
źródło
posElem.style = newStyle
działa we wszystkich przeglądarkach (działało dla mnie w przeglądarce Firefox)? Czy jestsetAttribute
to preferowane ze względów wydajnościowych , unikając malowania? CzyposElem.style.cssText = newStyle
zatem więcej perfomrantuposElem.style = newStyle
?metody ustawiania atrybutów (na przykład klasy) na elemencie: 1. el.className = string 2. el.setAttribute ('class', string) 3. el.attributes.setNamedItem (object) 4. el.setAttributeNode (node)
Zrobiłem prosty test porównawczy ( tutaj )
i wygląda na to, że setAttributeNode jest około 3 razy szybszy niż przy użyciu setAttribute.
więc jeśli problem stanowi wydajność - użyj „setAttributeNode”
źródło
Ciekawe wynos ze skryptu API Google temat dotyczące tego:
Robią to w ten sposób:
Zauważ, jak używają
setAttribute
do „src” i „nonce”, ale potem.async = ...
dla atrybutu „async”.Nie jestem w 100% pewien, ale prawdopodobnie dzieje się tak, ponieważ „asynchronizacja” jest obsługiwana tylko w przeglądarkach obsługujących bezpośrednie
.attr =
przypisanie. Więc nie ma sensu próbować,sestAttribute("async")
ponieważ jeśli przeglądarka nie rozumie.async=...
- nie zrozumie atrybutu „asynchronicznie”.Mam nadzieję, że jest to pomocne informacje z mojego bieżącego projektu badawczego „Un-minify GAPI” . Popraw mnie, jeśli się mylę.
źródło