Das DOM verhält sich bei einigen Dingen einfach ein wenig seltsam, und die Art und Weise, wie Sie mit Attributen umgehen, ist keine Ausnahme. Es gibt eine Reihe von Möglichkeiten, mit den Attributen von Elementen umzugehen. Mit Attributen meine ich Dinge wie das id in <div id="cool"></div>. Manchmal müssen Sie sie *setzen*. Manchmal müssen Sie sie *abrufen*. Manchmal gibt es schicke Hilfs-APIs. Manchmal gibt es keine.
Für diesen Artikel gehe ich davon aus, dass el ein DOM-Element in Ihrem JavaScript ist. Nehmen wir an, Sie haben etwas wie const el = document.querySelector("#cool"); gemacht und <div id="cool"> oder etwas Ähnliches gefunden.
Einige Attribute sind auch Attribute des DOM-Objekts selbst. Wenn Sie also ein id oder title setzen müssen, können Sie Folgendes tun:
el.id; // "cool"
el.title = "my title";
el.title; // "my title";
Andere, die sich so verhalten, sind lang, align und alle großen Ereignisse wie onclick.
Dann gibt es Attribute, die sich ähnlich verhalten, aber tiefer verschachtelt sind. Das style-Attribut ist so eines. Wenn Sie el.style ausgeben, sehen Sie eine Menge CSS-Stildeklarationen. Sie können sie einfach abrufen und setzen:
el.style.color = "red";
module.style.backgroundColor = "black";
Sie können auf diese Weise auch berechnete Farben abrufen. Wenn Sie module.style.color tun und hoffen, die Farbe eines Elements sofort zu erhalten, werden Sie sie wahrscheinlich nicht bekommen. Dafür müssten Sie Folgendes tun:
let style = window.getComputedStyle(el);
style.color; // whatever in CSS won out
Aber nicht alle Attribute sind wie diese erstklassigen Attribute.
el['aria-hidden'] = true; // nope
Das "funktioniert" in dem Sinne, dass es dies als Eigenschaft setzt, aber nicht auf die richtige Weise im DOM. Stattdessen müssen Sie die generischen Setter- und Getter-Funktionen verwenden, die für alle Attribute funktionieren, wie zum Beispiel:
el.setAttribute("aria-hidden", true);
el.getAttribute("aria-hidden");
Einige Attribute haben schicke Helfer. Der schickste ist classList für Klassenattribute. Bei einem Element wie:
<div class="module big"></div>
Hätten Sie:
el.classList.value; // "module big"
el.classList.length; // 2
el.classList.add("cool"); // adds the class "cool", so "module big cool"
el.classList.remove("big"); // removes "big", so "module cool"
el.classList.toggle("big"); // adds "big" back, because it was missing (goes back and forth)
el.classList.contains("module"); // true
Es gibt noch mehr, und classList selbst verhält sich wie ein Array, sodass Sie es mit forEach durchlaufen können und so weiter. Das ist ein ziemlich starker Grund, Klassen zu verwenden, da die DOM-API dafür so praktisch ist.
Ein weiterer Attributtyp, der eine etwas schicke Hilfe hat, ist data-*. Sagen wir, Sie haben:
<div data-active="true" data-placement="top right" data-extra-words="hi">test</div>
Sie haben dataset:
el.dataset;
/*
{
active: "true",
"placement", "top right"
*/
el.dataset.active; // "true"
el.dataset.extraWords; // "hi", note the conversion to camelCase
el.dataset.active = "false"; // setters work like this
Ich glaube, Sie müssen das Beispiel hinzufügen:
el.ariaHidden = true;
„…classList selbst verhält sich wie ein Array, sodass Sie es mit forEach durchlaufen können und so weiter“
Ich denke, dieser Satz ist etwas irreführend, da
classListeine **lebende DOMTokenList-Sammlung** und kein echtes Array ist. Daher können Sie zwar eineforEach-Methode darauf verwenden, aber keine anderen Array-bezogenen Methoden wiemap,filter,reduceusw. verwenden, ohne es zuerst in ein echtes Array zu konvertieren.Und dann haben wir .setAttributeNS und .getAttributeNS, wenn wir mit SVG arbeiten müssen...
Gibt es einen Leistungsunterschied zwischen
el.setAttribute("aria-hidden", true);undel.ariaHidden = true;?Andere zu berücksichtigende Punkte:
htmlForfür<label for="asdf">backgroundColorfürbackground-color, aberreadOnlynicht fürread-onlyundcontentEditablenicht fürcontent-editableel.checked = truevs.el.setAttribute('checked', true)el.classListvs.el.classNameist in Ordnung, aber warumel.datasetund nichtel.dataSetoderel.dataList?Ich denke, dieser Artikel könnte klarer sein. Erstens ist es hilfreicher, die DOM-Eigenschaften als Eigenschaften und nicht als "Attribute" zu bezeichnen, um Verwirrung zu vermeiden. Wie Sie sagen, werden viele Attribute als Eigenschaften auf dem entsprechenden DOM-Element gespiegelt, aber sie sind wirklich recht unterschiedliche Dinge, und es hilft, sie so zu betrachten, dann scheint es vielleicht nicht so seltsam. Einige wichtige Unterschiede:
Attributwerte (wie von
getAttributeabgerufen) sind immer Zeichenketten. Eigenschaften können jeden Typ haben (boolean, number,ClassListusw.).Attribut- und Eigenschaftsnamen stimmen aus verschiedenen Gründen nicht immer überein. Zum Beispiel JavaScript-Reservierte Wörter (
for/htmlFor) und Zustände von Formularelementen (daschecked-Attribut einer Checkbox oder eines Radiobuttons wird der EigenschaftdefaultCheckedzugeordnet, während die Eigenschaft checked kein entsprechendes Attribut hat).Werte stimmen möglicherweise nicht überein. URLs sind ein gutes Beispiel dafür. Wie in einem früheren Kommentar erwähnt, ist bei einem
<a>-Element dashref-Attribut nur die wörtliche Zeichenkette im HTML, während die entsprechende Eigenschaft eine vollqualifizierte URL ist.Im Allgemeinen ist das Attribut selbst in browserbasiertem JavaScript normalerweise nicht nützlich, und es ist hilfreicher, sich nur mit Eigenschaften zu befassen.
Ich bin mir nicht ganz sicher, ob es sinnvoll ist, einen Thread zu diesem Beitrag zu eröffnen, aber ich habe mich gefragt, wie Sie
data--Attribute in React-Apps handhaben. Kürzlich hatte ich einige Probleme beim Versuch,data--Attribute wie<Button data-role="foo" />zu übergeben, und der einzige Weg war, etwas wie Folgendes zu handhaben:const Button = ({...other
}) => (
<button data-role={other['data-role']} />
);
Gibt es einen besseren Ansatz?
classList ist kein Array und verhält sich auch nicht wie ein Array.
Es ist eine DOMTokenList und die DOMTokenList.forEach-Funktion ist im Internet Explorer nicht verfügbar.