A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.mozilla.org/de/docs/Web/API/Web_components/Using_templates_and_slots below:

Verwendung von Vorlagen und Slots - Web-APIs

Verwendung von Vorlagen und Slots

Dieser Artikel erklärt, wie Sie die <template>- und <slot>-Elemente verwenden können, um eine flexible Vorlage zu erstellen, die dann verwendet werden kann, um den Shadow DOM eines Webkomponenten auszufüllen.

Die Wahrheit über Vorlagen

Wenn Sie dieselben Markup-Strukturen wiederholt auf einer Webseite verwenden müssen, macht es Sinn, eine Art Vorlage zu verwenden, anstatt immer wieder dieselbe Struktur zu wiederholen. Dies war vorher möglich, aber es wird durch das HTML-<template>-Element erheblich erleichtert. Dieses Element und sein Inhalt werden nicht im DOM gerendert, können aber dennoch über JavaScript referenziert werden.

Schauen wir uns ein triviales, schnelles Beispiel an:

<template id="custom-paragraph">
  <p>My paragraph</p>
</template>

Dies wird nicht auf Ihrer Seite erscheinen, bis Sie mit JavaScript eine Referenz darauf erhalten und es dann dem DOM anhängen, indem Sie etwas wie das Folgende verwenden:

let template = document.getElementById("custom-paragraph");
let templateContent = template.content;
document.body.appendChild(templateContent);

Obwohl trivial, können Sie bereits sehen, wie nützlich dies sein könnte.

Verwendung von Vorlagen mit Webkomponenten

Vorlagen sind von alleine nützlich, aber sie funktionieren noch besser mit Webkomponenten. Lassen Sie uns eine Webkomponente definieren, die unsere Vorlage als Inhalt ihres Shadow DOM verwendet. Wir nennen sie ebenfalls <my-paragraph>:

customElements.define(
  "my-paragraph",
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById("custom-paragraph");
      let templateContent = template.content;

      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(templateContent.cloneNode(true));
    }
  },
);

Der entscheidende Punkt hier ist, dass wir einen Klon des Vorlageninhalts an den Shadow Root anhängen, der mit der Methode Node.cloneNode() erstellt wurde.

Und da wir ihren Inhalt an ein Shadow DOM anhängen, können wir einige Styling-Informationen innerhalb des Templates in einem <style>-Element einfügen, das dann in das benutzerdefinierte Element eingefasst wird. Dies würde nicht funktionieren, wenn wir es einfach zum Standard-DOM hinzufügen würden.

Also zum Beispiel:

<template id="custom-paragraph">
  <style>
    p {
      color: white;
      background-color: #666666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>

Nun können wir es einfach zu unserem HTML-Dokument hinzufügen:

<my-paragraph></my-paragraph>
Flexibilität mit Slots hinzufügen

Bisher so gut, aber das Element ist nicht sehr flexibel. Wir können nur ein Stück Text darin anzeigen, was bedeutet, dass es im Moment sogar weniger nützlich ist als ein normaler Absatz! Wir können es auf eine nette deklarative Weise ermöglichen, unterschiedlichen Text in jeder Elementinstanz anzuzeigen, indem wir das <slot>-Element verwenden.

Slots werden durch ihr name-Attribut identifiziert und ermöglichen Ihnen, Platzhalter in Ihrer Vorlage zu definieren, die mit beliebigen Markup-Fragmenten gefüllt werden können, wenn das Element im Markup verwendet wird.

Wenn wir also einen Slot in unser triviales Beispiel einfügen wollen, können wir das Vorlagen-Absatz-Element wie folgt aktualisieren:

<p><slot name="my-text">My default text</slot></p>

Wenn der Slot-Inhalt nicht definiert ist, wenn das Element im Markup eingefügt ist, oder wenn der Browser Slots nicht unterstützt, enthält <my-paragraph> einfach den Fallback-Text "My default text".

Um den Slot-Inhalt zu definieren, fügen wir eine HTML-Struktur innerhalb des <my-paragraph>-Elements ein, mit einem slot-Attribut, dessen Wert gleich dem Namen des Slots ist, den wir füllen möchten. Wie zuvor, kann dies alles sein, was Sie möchten, zum Beispiel:

<my-paragraph>
  <span slot="my-text">Let's have some different text!</span>
</my-paragraph>

oder

<my-paragraph>
  <ul slot="my-text">
    <li>Let's have some different text!</li>
    <li>In a list!</li>
  </ul>
</my-paragraph>

Hinweis: Knoten, die in Slots eingefügt werden können, werden als Slottable Knoten bezeichnet; wenn ein Knoten in einen Slot eingefügt wurde, sagt man, er sei eingeschoben.

Das war's für unser triviales Beispiel. Wenn Sie noch mehr damit herumspielen wollen, können Sie es auf GitHub finden (sehen Sie es laufend live).

Das name-Attribut sollte pro Shadow Root eindeutig sein: Wenn Sie zwei Slots mit demselben Namen haben, werden alle Elemente mit einem passenden slot-Attribut dem ersten Slot mit diesem Namen zugewiesen. Aber das slot-Attribut muss nicht eindeutig sein: Ein <slot> kann von mehreren Elementen gefüllt werden, die alle ein übereinstimmendes slot-Attribut haben.

Die name- und slot-Attribute sind beide standardmäßig leerzeichen, so dass Elemente ohne slot-Attribute dem <slot> mit keinem name-Attribut zugewiesen werden (dem unbenannten Slot oder Standardslot). Hier ist ein Beispiel:

<template id="custom-paragraph">
  <style>
    p {
      color: white;
      background-color: #666666;
      padding: 5px;
    }
  </style>
  <p>
    <slot name="my-text">My default text</slot>
    <slot></slot>
  </p>
</template>

Sie können es dann so verwenden:

<my-paragraph>
  <span slot="my-text">Let's have some different text!</span>
  <span>This will go into the unnamed slot</span>
  <span>This will also go into the unnamed slot</span>
</my-paragraph>

In diesem Beispiel:

Ein komplexeres Beispiel

Um den Artikel abzuschließen, schauen wir uns etwas weniger Triviales an.

Die folgenden Codeausschnitte zeigen, wie man <slot> zusammen mit <template> und etwas JavaScript verwenden kann, um:

Beachten Sie, dass es technisch möglich ist, das <slot>-Element ohne ein <template>-Element zu verwenden, z.B. innerhalb eines regulären <div>-Elements, und dennoch die Platzhalterfunktionen von <slot> für Shadow DOM-Inhalte zu nutzen, und dies kann tatsächlich die kleine Mühe vermeiden, zuerst auf die content-Eigenschaft des Vorlagelements (und dessen Klon) zugreifen zu müssen. Es ist jedoch im Allgemeinen praktischer, Slots innerhalb eines <template>-Elements hinzuzufügen, da Sie wahrscheinlich kein Muster basierend auf einem bereits gerenderten Element definieren müssen.

Außerdem, selbst wenn es noch nicht gerendert ist, sollte die Zweckbestimmung des Containers als Vorlage semantisch klarer sein, wenn das <template> verwendet wird. Darüber hinaus kann <template> Objekte direkt hinzugefügt bekommen, wie <td>, die verschwinden würden, wenn sie in ein <div> eingefügt werden.

Hinweis: Sie können dieses komplette Beispiel bei element-details finden (sehen Sie es laufend live).

Erstellen einer Vorlage mit einigen Slots

Zunächst verwenden wir das <slot>-Element innerhalb eines <template>-Elements, um ein neues "element-details-template" Dokumentfragment mit einigen benannten Slots zu erstellen:

<template id="element-details-template">
  <style>
    details {
      font-family: "Open Sans Light", Helvetica, Arial;
    }
    .name {
      font-weight: bold;
      color: #217ac0;
      font-size: 120%;
    }
    h4 {
      margin: 10px 0 -8px 0;
    }
    h4 span {
      background: #217ac0;
      padding: 2px 6px 2px 6px;
    }
    h4 span {
      border: 1px solid #cee9f9;
      border-radius: 4px;
    }
    h4 span {
      color: white;
    }
    .attributes {
      margin-left: 22px;
      font-size: 90%;
    }
    .attributes p {
      margin-left: 16px;
      font-style: italic;
    }
  </style>
  <details>
    <summary>
      <span>
        <code class="name"
          >&lt;<slot name="element-name">NEED NAME</slot>&gt;</code
        >
        <span class="desc"
          ><slot name="description">NEED DESCRIPTION</slot></span
        >
      </span>
    </summary>
    <div class="attributes">
      <h4><span>Attributes</span></h4>
      <slot name="attributes"><p>None</p></slot>
    </div>
  </details>
  <hr />
</template>

Dieses <template>-Element hat mehrere Merkmale:

Erstellen eines neuen <element-details>-Elements aus der <template>

Als nächstes erstellen wir ein neues benutzerdefiniertes Element namens <element-details> und verwenden Element.attachShadow, um daran als sein Shadow Root das Dokumentfragment, das wir mit unserem <template>-Element oben erstellt haben, anzuhängen. Dies verwendet genau dasselbe Muster, das wir in unserem früheren trivialen Beispiel gesehen haben.

customElements.define(
  "element-details",
  class extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById(
        "element-details-template",
      ).content;
      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(template.cloneNode(true));
    }
  },
);
Verwenden des <element-details>-Benutzerelements mit benannten Slots

Nun nehmen wir das <element-details>-Element und verwenden es tatsächlich in unserem Dokument:

<element-details>
  <span slot="element-name">slot</span>
  <span slot="description"
    >A placeholder inside a web component that users can fill with their own
    markup, with the effect of composing different DOM trees together.</span
  >
  <dl slot="attributes">
    <dt>name</dt>
    <dd>The name of the slot.</dd>
  </dl>
</element-details>

<element-details>
  <span slot="element-name">template</span>
  <span slot="description"
    >A mechanism for holding client- side content that is not to be rendered
    when a page is loaded but may subsequently be instantiated during runtime
    using JavaScript.</span
  >
</element-details>

Beachten Sie bei diesem Snippet folgende Punkte:

Ein abschließendes bisschen Stil hinzufügen

Abschließend fügen wir ein kleines bisschen mehr CSS für die <dl>, <dt> und <dd>-Elemente in unserem Dokument hinzu:

dl {
  margin-left: 6px;
}
dt {
  color: #217ac0;
  font-family: Consolas, "Liberation Mono", Courier;
  font-size: 110%;
  font-weight: bold;
}
dd {
  margin-left: 16px;
}
body {
  margin-top: 47px;
}
Ergebnis

Schließlich setzen wir alle Snippets zusammen und sehen uns an, wie das gerenderte Ergebnis aussieht.

Beachten Sie die folgenden Punkte zu diesem gerenderten Ergebnis:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4