Mit benutzerdefinierten Elementen können Sie Ihre eigenen HTML-Tags erstellen. Diese Checkliste enthält Best Practices für die Erstellung qualitativ hochwertiger Elemente.
Mit benutzerdefinierten Elementen können Sie HTML erweitern und eigene Tags definieren. Sie sind ein
ist eine leistungsstarke Funktion, die aber nicht besonders schlecht ist.
immer klar sein, wie Sie Ihr eigenes Element am besten implementieren.
Um Ihnen die bestmögliche Erfahrung zu bieten, haben wir
Checkliste. Sie schlüsselt all die Dinge auf, die wir für
gut funktioniertes benutzerdefiniertes Element.
Checkliste
Schatten-DOM
Erstellen Sie einen Schattenstamm, um Stile zu kapseln. |
Warum? |
Durch die Kapselung von Stilen im Schattenstamm Ihres Elements wird sichergestellt, dass es funktioniert.
unabhängig davon, wo sie verwendet werden. Das ist besonders wichtig,
Ihr Element innerhalb des Schattenstamms eines anderen Elements platzieren möchte. Dieses
gilt auch für einfache Elemente wie Kästchen oder Optionsfelder. Möglicherweise
Der einzige Inhalt innerhalb des Schattenstamms sind die Stile
selbst.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Erstellen Sie den Schattenstamm im Konstruktor.
|
Warum? |
Für den Konstruktor haben Sie exklusive Kenntnisse Ihres Elements.
Jetzt sollten Sie Details zur Implementierung festlegen, die Sie nicht
Elemente, die das Problem verursachen. Dies geschieht in einem späteren Callback wie dem
connectedCallback bedeutet, dass Sie vor
in denen Ihr Element getrennt und dann wieder an das Dokument angehängt wird.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Platzieren Sie alle untergeordneten Elemente, die vom Element erstellt werden, in den Schattenstamm.
|
Warum? |
Von Ihrem Element erstellte untergeordnete Elemente sind Teil seiner Implementierung und sollten
privat. Ohne den Schutz eines Schattenstamms können externe JavaScript-Dateien
die diese Kinder unbeabsichtigt stören könnten.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-tabs> -Element.
|
<slot> verwenden um Light-DOM-Child in Ihr Shadow DOM zu projizieren
|
Warum? |
Ermöglichen Sie Nutzern Ihrer Komponente, Inhalte in Ihrer Komponente anzugeben, da durch untergeordnete HTML-Elemente Ihre Komponente besser zusammensetzbar ist. Wenn ein Browser keine benutzerdefinierten Elemente unterstützt, bleibt der verschachtelte Inhalt verfügbar, sichtbar und zugänglich.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-tabs> -Element.
|
Anzeigestil für :host festlegen (z.B. block ,
inline-block , flex ), es sei denn, Sie bevorzugen die Standardeinstellung
inline
|
Warum? |
Benutzerdefinierte Elemente sind standardmäßig auf display: inline gesetzt.
width oder height haben keine Auswirkungen. So oft
für Entwickler überrascht und zu Problemen in Bezug auf
Layout der Seite. Sofern Sie kein inline -Display bevorzugen,
sollte immer einen Standardwert für display festlegen.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Fügen Sie einen :host -Anzeigestil hinzu, der das ausgeblendete Attribut berücksichtigt.
|
Warum? |
Ein benutzerdefiniertes Element mit einem Standardformat für display , z.B.
:host { display: block } , überschreibt die niedrigere Spezifität
integriert
<ph type="x-smartling-placeholder"></ph>
hidden -Attribut.
Dies könnte Sie überraschen, wenn Sie das Festlegen des hidden erwarten.
auf Ihrem Element, um es display: none zu rendern. Außerdem
auf einen display -Standardstil angewendet, jetzt Unterstützung für hidden hinzufügen
mit :host([hidden]) { display: none } .
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Attribute und Eigenschaften
Überschreiben Sie keine globalen Attribute vom Typ "author-set".
|
Warum? |
Globale Attribute sind Attribute, die in allen HTML-Elementen vorhanden sind. Einige
Beispiele sind tabindex und role . Ein benutzerdefiniertes Element
kann die anfängliche tabindex auf 0 setzen, damit sie über die Tastatur erfolgt.
fokussierbar. Sie sollten jedoch immer zuerst prüfen, ob der Entwickler
Ihr Element hat dies auf einen anderen Wert gesetzt. Wenn zum Beispiel
tabindex bis -1 ist das ein Signal dafür, dass das
-Elements interaktiv sein.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element. Dies wird unter
Überschreiben Sie nicht den Seitenautor.
|
Primitive Daten (Strings, Zahlen, boolesche Werte) immer als Attribute akzeptieren
oder Eigenschaften.
|
Warum? |
Benutzerdefinierte Elemente sollten wie ihre integrierten Entsprechungen konfigurierbar sein.
Die Konfiguration kann deklarativ, über Attribute oder imperativ übergeben werden.
über JavaScript-Eigenschaften. Idealerweise sollte jedes Attribut auch mit
eine entsprechende Property.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Versuchen Sie, primitive Datenattribute und Eigenschaften synchron zu halten,
und umgekehrt.
|
Warum? |
Sie wissen nie, wie Nutzende mit Ihrem Element interagieren werden. Sie könnten
eine Eigenschaft in JavaScript festlegen und dann erwarten,
mit einer API wie getAttribute() . Wenn jedes Attribut
und beide reflektieren, können Nutzer
mit Ihrem Element zu arbeiten. Mit anderen Worten: Das Aufrufen
setAttribute('foo', value) sollte auch eine entsprechende
foo und umgekehrt. Natürlich gibt es Ausnahmen für
für diese Regel. Sie sollten keine Eigenschaften mit hoher Häufigkeit reflektieren, z.B.
currentTime in einem Videoplayer. Entscheiden Sie selbst. Wenn es
Es scheint, als würde ein Nutzer mit einer Property oder einem Attribut interagieren.
ist es nicht schwer, das zu reflektieren.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element. Dies wird unter
Rücknahmeprobleme vermeiden:
|
Versuchen Sie, nur Rich-Daten (Objekte, Arrays) als Eigenschaften zu akzeptieren.
|
Warum? |
Im Allgemeinen gibt es keine Beispiele für integrierte HTML-Elemente, die
Rich-Daten (einfache JavaScript-Objekte und Arrays) über ihre
Attribute. Rich-Daten werden stattdessen entweder über Methodenaufrufe oder
Eigenschaften. Es gibt einige offensichtliche Nachteile,
Die Serialisierung eines großen Objekts in einem String kann teuer sein.
Dabei gehen alle Objektverweise verloren. Für
Wenn Sie z. B. ein Objekt als String
angeben, das einen Verweis auf ein anderes Objekt hat,
oder vielleicht auf einen DOM-Knoten, gehen diese Bezüge verloren.
|
Rich-Daten-Eigenschaften für Attribute nicht darstellen.
|
Warum? |
Das Abbilden umfangreicher Dateneigenschaften
in Attribute ist unnötig teuer.
die Serialisierung und Deserialisierung
derselben JavaScript-Objekte erfordern. Es sei denn,
gibt es einen Anwendungsfall, der nur mit dieser Funktion gelöst werden kann, ist es wahrscheinlich,
vermeiden sollten.
|
Prüfen Sie, ob Eigenschaften vorhanden sind, die möglicherweise vor dem Element festgelegt wurden.
aktualisiert.
|
Warum? |
Ein Entwickler, der Ihr Element verwendet, kann versuchen, eine Eigenschaft für das Element festzulegen
bevor die Definition geladen wurde. Dies gilt insbesondere, wenn das
das Laden von Komponenten übernimmt,
mit der Seite verknüpft und ihre Properties an ein Modell gebunden.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element. Weitere Erläuterungen finden Sie unter
Machen Sie Properties faul.
|
Wenden Sie die Kurse nicht selbst an.
|
Warum? |
Elemente, die ihren Status ausdrücken müssen, sollten dies mithilfe von Attributen tun. Die
wird im Allgemeinen davon ausgegangen, dass das Attribut class dem
und selbst etwas schreiben kann,
und Entwicklerkursen.
|
Ereignisse
Löst Ereignisse als Reaktion auf interne Komponentenaktivitäten aus.
|
Warum? |
Ihre Komponente kann Eigenschaften aufweisen, die sich als Reaktion auf Aktivitäten ändern, die
nur Ihre Komponente weiß,
beispielsweise ob ein Timer oder eine Animation
oder eine Ressource vollständig geladen ist. Es ist hilfreich, Ereignisse
um den Host zu informieren, dass der Status der Komponente
unterscheiden.
|
Keine Ereignisse auslösen, wenn der Host ein Attribut festlegt (abwärts
Datenfluss).
|
Warum? |
Das Auslösen eines Ereignisses als Reaktion auf die Festlegung einer Eigenschaft durch den Host ist überflüssig
(Der Host kennt den aktuellen Status, da er ihn gerade festgelegt hat.) Ereignisse auslösen
Als Reaktion auf eine Hosteinstellung kann eine Eigenschaft Endlosschleifen mit Daten verursachen
Bindungssysteme.
|
Beispiel |
Die <ph type="x-smartling-placeholder"></ph>
<howto-checkbox> -Element.
|
Erklärvideos
Seitenautor nicht überschreiben
Es ist möglich, dass ein Entwickler, der Ihr Element verwendet, einige
in den Ausgangszustand versetzt. Ändern der ARIA-role
oder der Fokussierbarkeit mit
tabindex
. Überprüfen Sie, ob diese und
andere globale Attribute festgelegt wurden.
bevor Sie Ihre eigenen Werte anwenden.
connectedCallback() {
if (!this.hasAttribute('role'))
this.setAttribute('role', 'checkbox');
if (!this.hasAttribute('tabindex'))
this.setAttribute('tabindex', 0);
Eigenschaften faul machen
Ein Entwickler könnte versuchen, eine Eigenschaft für ein Element festzulegen, bevor
Definition wurde geladen. Dies gilt insbesondere, wenn der Entwickler
Framework, das das Laden von Komponenten, das Einfügen dieser Komponenten auf die Seite
Bindung ihrer Attribute an ein Modell.
Im folgenden Beispiel bindet Angular die Funktion
isChecked
zur checked
-Eigenschaft des Kästchens hinzu. Wenn die Definition für
wenn ein Lazy Loading für die Anleitung aktiviert war.
die ausgewählte Eigenschaft ein, bevor das Element aktualisiert wurde.
<howto-checkbox [checked]="defaults.isChecked"></howto-checkbox>
Ein benutzerdefiniertes Element sollte für dieses Szenario geeignet sein, indem geprüft wird, ob Eigenschaften
für die Instanz festgelegt ist. Die <howto-checkbox>
veranschaulicht dieses Muster mithilfe der Methode _upgradeProperty()
.
connectedCallback() {
...
this._upgradeProperty('checked');
}
_upgradeProperty(prop) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
_upgradeProperty()
erfasst den Wert aus der nicht aktualisierten Instanz und löscht
der Eigenschaft fest, damit sie den eigenen Eigenschaften-Setter des benutzerdefinierten Elements nicht verdeckt.
Wenn die Definition des Elements schließlich geladen wird, kann sie
den richtigen Zustand widerspiegelt.
Rücknahmeprobleme vermeiden
Es ist verlockend, den attributeChangedCallback()
zu verwenden, um den Zustand
zugrunde liegende Property. Beispiel:
// When the [checked] attribute changes, set the checked property to match.
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'checked')
this.checked = newValue;
}
Dies kann jedoch eine Endlosschleife erzeugen, wenn der Eigenschafts-Setter auch
das Attribut.
set checked(value) {
const isChecked = Boolean(value);
if (isChecked)
// OOPS! This will cause an infinite loop because it triggers the
// attributeChangedCallback() which then sets this property again.
this.setAttribute('checked', '');
else
this.removeAttribute('checked');
}
Alternativ können Sie zulassen, dass der Property-Setter das Attribut reflektiert.
Sie lassen den Getter seinen Wert anhand des Attributs bestimmen.
set checked(value) {
const isChecked = Boolean(value);
if (isChecked)
this.setAttribute('checked', '');
else
this.removeAttribute('checked');
}
get checked() {
return this.hasAttribute('checked');
}
In diesem Beispiel wird durch das Hinzufügen oder Entfernen des Attributs auch die Eigenschaft festgelegt.
Schließlich können mit attributeChangedCallback()
Nebenwirkungen verarbeitet werden.
wie das Anwenden von ARIA-Zuständen.
attributeChangedCallback(name, oldValue, newValue) {
const hasValue = newValue !== null;
switch (name) {
case 'checked':
// Note the attributeChangedCallback is only handling the *side effects*
// of setting the attribute.
this.setAttribute('aria-checked', hasValue);
break;
...
}
}