Éléments personnalisés des composants Web

Un didacticiel d'introduction aux éléments personnalisés

J'ai écrit mon premier élément personnalisé en utilisant une bibliothèque CSS appelée CSS Doodle. C'est une application incroyable qui utilise des éléments personnalisés pour vous permettre de créer de superbes animations CSS. Cela a déverrouillé un tout nouveau désir de comprendre comment cela fonctionne sous le capot. J'ai donc décidé de mieux regarder les composants Web en général, un sujet sur lequel beaucoup de gens m'ont demandé d'écrire.

Les éléments personnalisés nous permettent de créer de nouvelles balises HTML.

Je ne pouvais pas imaginer pourquoi cela pourrait être utile jusqu'à ce que j'utilise cette bibliothèque CSS Doodle. Après tout, nous avons déjà beaucoup de balises.

Ce tutoriel couvre Custom Elements version 1, la dernière version de la norme au moment de la rédaction

En utilisant des éléments personnalisés, nous pouvons créer une balise HTML personnalisée avec CSS et JavaScript associés.

Ce n'est pas une alternative aux frameworks comme React, Angular ou Vue, mais c'est un tout nouveau concept.

Lewindowobjet global expose uncustomElementspropriété qui nous donne accès à unCustomElementRegistryobjet.

LeCustomElementRegistryobjet

Cet objet dispose de plusieurs méthodes que nous pouvons utiliser pour enregistrer les éléments personnalisés et interroger les éléments personnalisés déjà enregistrés:

  • define()utilisé pour définir un nouvel élément personnalisé
  • get()utilisé pour obtenir le constructeur d'un élément personnalisé (retourneundefineds'il n'existe pas)
  • upgrade()pour mettre à niveau un élément personnalisé
  • whenDefined()utilisé pour obtenir le constructeur d'un élément personnalisé. Similaire àget(), mais il renvoie une promesse à la place, qui se résout lorsque l'élément est disponible.

Comment créer un élément personnalisé

Avant de pouvoir appeler lewindow.customElements.define(), nous devons définir un nouvel élément HTML en créant une nouvelle classe qui étend la classe intégrée HTMLElement:

class CustomTitle extends HTMLElement {
	//...
}

Dans le constructeur de classe que nous allons utiliserDOM de l'ombrepour associer CSS, JavaScript et HTML personnalisés à notre nouvelle balise.

De cette façon, tout ce que nous verrons dans le HTML est notre balise, mais cela encapsulera beaucoup de fonctionnalités.

Nous commençons par initialiser le constructeur:

class CustomTitle extends HTMLElement {
  constructor() {
    super()
    //...
  }
}

Ensuite, nous appelons leattachShadow()méthode du HTMLElement en passant un objet avec lemodepropriété définie sur'open'. Cette propriété définit le mode d'encapsulation pour le DOM shadow. Si c'estopennous pouvons accéder aushadowRootpropriété d'un élément. S'il est fermé, nous ne pouvons pas.

Voici comment procéder:

class CustomTitle extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
    //...
  }
}

Quelques exemples que vous trouverez utilisent la syntaxeconst shadowRoot = this.attachShadow(/* ... */)mais vous pouvez l'éviter à moins que vous ne définissiezmodeàclosed, car vous pouvez toujours référencer cet objet en appelantthis.shadowRoot.

C'est ce que nous allons faire maintenant, pour en définir le innerHTML:

class CustomTitle extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
    this.shadowRoot.innerHTML = `
      <h1>My Custom Title!</h1>
    `
  }
}

Vous pouvez ajouter autant de balises que vous le souhaitez, vous n'êtes pas limité à une balise à l'intérieur duinnerHTMLbiens

Maintenant, nous ajoutons cet élément nouvellement défini àwindow.customElements:

window.customElements.define('custom-title', CustomTitle)

et nous pouvons utiliser le<custom-title></custom-title>Élément personnalisé dans la page!

Remarque: vous ne pouvez pas utiliser de balises à fermeture automatique (en d'autres termes: ceci<custom-title />n'est pas autorisé par la norme)

Remarquez le-tiret dans le nom de la balise.Nous devons utiliser un tiretdans un élément personnalisé. C'est ainsi que nous pouvons détecter une balise intégrée à partir d'une balise personnalisée.

Maintenant, nous avons cet élément dans la page, et nous pouvons faire ce que nous faisons avec d'autres balises: ciblez-le avec CSS et JavaScript!

Fournissez un CSS personnalisé pour l'élément

Dans le constructeur, vous pouvez passer unstylebalise en plus de la balise HTML qui définit le contenu, et à l'intérieur, vous pouvez avoir le CSS d'élément personnalisé:

class CustomTitle extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
    this.shadowRoot.innerHTML = `
      <style>
        h1 {
          font-size: 7rem;
          color: #000;
          font-family: Helvetica;
          text-align: center;
        }
      </style>
      <h1>My Custom Title!</h1>
    `
  }
}

Voici l'exemple d'élément personnalisé que nous avons créé, dans Codepen:

Voir le styloComposants Web, mon titre personnalisépar Flavio Copes (@flaviocopes) surCodePen.

Tech Wiki Online!