Abschnitt 11 · Lektion 2
Attribute setzen
Nicht jede Änderung an der Seite ist Text. Genauso oft geht es um ein Attribut: ein Link bekommt ein anderes Ziel, ein Knopf wird gesperrt, ein Bild bekommt eine Beschreibung.
Der allgemeine Weg
<a id="link" href="/lernen">Zum Katalog</a>
<img id="bild" src="kaputt.png"> body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 0;
padding: 1rem;
line-height: 1.6;
color: #1c1917;
} const link = document.getElementById("link");
const bild = document.getElementById("bild");
// Setzen. Gibt es das Attribut schon, wird es überschrieben.
link.setAttribute("href", "/lernen/javascript");
link.setAttribute("title", "Der JavaScript-Kurs");
bild.setAttribute("alt", "Ein Beispielbild");
// Fragen.
console.log("hat title?", link.hasAttribute("title"));
console.log("hat target?", link.hasAttribute("target"));
// Entfernen.
link.removeAttribute("title");
console.log("und jetzt?", link.hasAttribute("title"));
// Was am Ende im Markup steht.
console.log(link.outerHTML); Drei Methoden decken alles ab, was mit Attributen zu tun hat.
setAttribute("href", "/lernen/javascript") setzt ein Attribut. Gibt es das Attribut schon, wird sein Wert überschrieben, sonst kommt es dazu. Der Wert ist immer Text, auch wenn du eine Zahl übergibst.
hasAttribute("title") fragt, ob es da ist, und liefert true oder false.
removeAttribute("title") nimmt es weg. Ein Attribut auf "" zu setzen ist nicht dasselbe: dann ist es weiterhin da, nur eben leer.
Diese drei funktionieren bei jedem Attribut. Damit kommst du überall hin.
Der direkte Weg
<input id="eins" type="text" value="Anfang">
<input id="zwei" type="text" value="Anfang">
<input id="drei" type="text" value="Anfang"> body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 0;
padding: 1rem;
line-height: 1.6;
color: #1c1917;
}
button,
input,
select,
textarea {
font: inherit;
}
input,
select,
textarea {
padding: 0.35rem 0.5rem;
border: 1px solid #d6d3d1;
border-radius: 6px;
} const eins = document.getElementById("eins");
const zwei = document.getElementById("zwei");
const drei = document.getElementById("drei");
// Der direkte Weg über die Eigenschaft. Kurz und lesbar.
eins.disabled = true;
eins.value = "gesperrt";
console.log("eins gesperrt?", eins.disabled);
// Dasselbe über das Attribut. Der Wert ist dabei egal,
// es zählt nur, dass das Attribut da ist.
zwei.setAttribute("disabled", "");
console.log("zwei gesperrt?", zwei.disabled);
// Und jetzt die Falle: das hier gibt nichts frei.
drei.setAttribute("disabled", "false");
console.log("drei gesperrt?", drei.disabled);
// Freigeben geht nur so.
drei.disabled = false;
console.log("drei jetzt noch gesperrt?", drei.disabled); Für viele Attribute gibt es zusätzlich eine Eigenschaft am Element: el.id, el.href, el.value, el.disabled. Die ist kürzer zu schreiben und meistens die bessere Wahl.
In Lektion 10.5 ging es beim Lesen darum, dass die beiden auseinanderlaufen können: getAttribute("href") liefert den Text aus dem Markup, link.href die aufgelöste Adresse. Beim Schreiben gibt es einen zweiten Unterschied, und der ist folgenreicher.
Bei Boolean-Attributen zählt nur die Anwesenheit. disabled, checked, required, readonly, hidden: entweder das Attribut steht im Markup, dann gilt es, oder es steht nicht da, dann gilt es nicht. Sein Wert ist völlig egal.
Das führt zu der Zeile, die im dritten Beispielfeld steht: setAttribute("disabled", "false") sperrt das Feld. Es sieht aus wie eine Freigabe und ist eine Sperre, denn das Attribut ist jetzt da. Freigeben geht nur mit removeAttribute("disabled") oder, viel lesbarer, mit el.disabled = false.
Die Regel: Bei Boolean-Attributen nimmst du die Eigenschaft. el.disabled = true und el.disabled = false sind eindeutig, kurz und lassen sich nicht falsch verstehen.
Ein Nachschlag für die Eingabezeile der Console: Am Ende des Beispiels ist drei wieder frei. Frag dort document.getElementById("drei").getAttribute("disabled"), und die Antwort ist null. Die Eigenschaft hat das Attribut also nicht überstimmt, sie hat es weggenommen.
Eigene Daten schreiben
<button id="knopf" type="button" data-zustand="ruht">Speichern</button> body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 0;
padding: 1rem;
line-height: 1.6;
color: #1c1917;
}
button,
input,
select,
textarea {
font: inherit;
}
button {
padding: 0.4rem 0.8rem;
border: 1px solid #d6d3d1;
border-radius: 6px;
background: #fafaf9;
cursor: pointer;
} const knopf = document.getElementById("knopf");
console.log("vorher:", knopf.dataset.zustand);
// Schreiben geht genauso wie Lesen.
knopf.dataset.zustand = "laeuft";
console.log("nachher:", knopf.dataset.zustand);
console.log("im Markup:", knopf.getAttribute("data-zustand"));
// Ein neuer Name legt ein neues Attribut an. Aus kursId
// wird dabei data-kurs-id, die Umschreibung läuft rückwärts.
knopf.dataset.kursId = "js";
console.log(knopf.outerHTML);
// Wegnehmen geht mit delete.
delete knopf.dataset.kursId;
console.log("danach:", knopf.outerHTML); Lesen aus dataset kennst du aus Lektion 10.5. Schreiben geht genauso: knopf.dataset.zustand = "laeuft" setzt das Attribut data-zustand.
Die Umschreibung zwischen den beiden Schreibweisen läuft dabei rückwärts genauso wie vorwärts. dataset.kursId erzeugt data-kurs-id: vor jedem Großbuchstaben ein Bindestrich, der Buchstabe wird klein.
Wegnehmen geht mit delete knopf.dataset.kursId, und das ist eines der wenigen Male in diesem Kurs, dass delete überhaupt vorkommt.
Klasse oder Datenfeld
Beides beschreibt etwas am Element, und die Trennung lohnt sich:
Eine Klasse ist ein Zustand, den es gibt oder nicht: ist-aktiv, ist-versteckt, hat-fehler. Sie hängt am Aussehen, und deshalb steht die zugehörige Regel im Stylesheet. Lektion 11.3 macht daraus das Werkzeug für alles Sichtbare.
Ein Datenfeld ist ein Wert: data-kurs-id="js", data-preis-cent="4900", data-zustand="laeuft". Es hängt an den Daten, nicht am Aussehen, und drei mögliche Zustände in drei Klassen zu gießen wird schnell unübersichtlich.
Der praktische Grund kommt in Abschnitt 12: wenn du auf einen Klick reagierst, willst du wissen, welcher Eintrag gemeint war. Ein data-id am Element beantwortet das in einer Zeile.
Und die aria-Attribute
aria-expanded, aria-invalid, aria-live: das sind ganz gewöhnliche Attribute und werden mit setAttribute gesetzt wie alle anderen. Eigene Eigenschaften gibt es inzwischen auch (el.ariaExpanded), dieser Kurs bleibt trotzdem bei setAttribute("aria-expanded", "true"): die Schreibweise sieht für jedes aria--Attribut gleich aus, und du musst dir keine zweite Namensliste merken.
Sie sagen Screenreadern, was auf der Seite gerade los ist. Welche du wirklich brauchst und wann, steht in Lektion 20.4. Hier reicht: sie sind nichts Besonderes, du setzt sie genau wie ein title.
Zum Mitnehmen
Bei Boolean-Attributen zählt nur, ob sie da sind. setAttribute("disabled", "false") sperrt das Feld, statt es freizugeben.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.