Aller au contenu

Éléments personnalisés

Les éléments personnalisés représentent l'un des piliers fondamentaux des Web Components, permettant aux développeurs de définir leurs propres balises et composants HTML. Cette capacité étend le vocabulaire HTML standard, permettant la création d'éléments réutilisables et encapsulés avec un comportement personnalisé. Plongeons plus profondément dans le monde des éléments personnalisés et découvrons comment exploiter leur puissance.

Définir un élément personnalisé

Pour créer un élément personnalisé, nous utilisons la syntaxe class en JavaScript pour définir une nouvelle classe qui hérite de la classe intégrée HTMLElement. Cette classe encapsule le comportement et les propriétés de l'élément. Une fois définie, nous l'enregistrons dans le navigateur à l'aide de customElements.define().

Exemple : Création d'un élément personnalisé simple


html
<my-custom-element></my-custom-element>
<script>
  class MyCustomElement extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.innerHTML = `<p>Hello, World!</p>`;
    }
  }
  
  customElements.define('my-custom-element', MyCustomElement);
</script>

Cet exemple définit un élément personnalisé simple nommé my-custom-element qui affiche « Hello, World! » à l'intérieur d'un shadow DOM. Pour utiliser cet élément, ajoutez simplement <code><my-custom-element></code> à votre HTML.

note

Les éléments personnalisés v1 sont pris en charge par tous les navigateurs modernes (Chrome 54+, Firefox 52+, Safari 10.1+, Edge 79+). Vérifiez toujours la compatibilité des navigateurs si vous ciblez des environnements hérités.

Callbacks du cycle de vie

Les éléments personnalisés disposent d'un ensemble de callbacks du cycle de vie qui permettent aux développeurs d'exécuter du code à des étapes spécifiques du cycle de vie de l'élément :

  • connectedCallback() : Invoquée chaque fois que l'élément personnalisé est ajouté à un élément connecté au document.
  • disconnectedCallback() : Invoquée chaque fois que l'élément personnalisé est déconnecté du DOM du document.
  • attributeChangedCallback(name, oldValue, newValue) : Invoquée chaque fois qu'un des attributs de l'élément personnalisé est ajouté, supprimé ou modifié.
  • adoptedCallback() : Invoquée chaque fois que l'élément personnalisé est déplacé vers un nouveau document.
CallbackMoment du déclenchement
connectedCallback()L'élément est ajouté au DOM
disconnectedCallback()L'élément est supprimé du DOM
attributeChangedCallback(name, oldValue, newValue)Un attribut observé change
adoptedCallback()L'élément est déplacé vers un nouveau document

Exemple : Utilisation des callbacks du cycle de vie


javascript
<lifecycle-element></lifecycle-element>
<script>
class LifecycleElement extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `
      <style>
        #status {
          color: blue;
          font-weight: bold;
        }
      </style>
      <p>Lifecycle Element</p>
      <p id="status">Element not connected</p>
    `;
  }

  connectedCallback() {
    this.shadowRoot.getElementById('status').textContent = 'Element connected to the page.';
  }

  disconnectedCallback() {
    this.shadowRoot.getElementById('status').textContent = 'Element disconnected from the page.';
  }
}

customElements.define('lifecycle-element', LifecycleElement);
</script>

Attributs et propriétés

Les éléments personnalisés peuvent avoir des attributs et des propriétés pour gérer leur état et leur comportement. Les attributs sont définis directement dans le HTML et sont toujours des chaînes de caractères, tandis que les propriétés sont définies sur l'objet DOM de l'élément et peuvent être de n'importe quel type de données. Notez que attributeChangedCallback ne se déclenche que pour les attributs explicitement listés dans la méthode static get observedAttributes() de l'élément.

Exemple : Gestion des attributs et des propriétés


javascript
<attribute-element id="element" data-content="Initial content"></attribute-element>
<button onclick="buttonClicked()">Click to change attribute</button>
<script>
  class AttributeElement extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.innerHTML = `<p>Attribute Example: <span id="content"></span></p>`;
    }
  
    static get observedAttributes() {
      return ['data-content'];
    }
  
    attributeChangedCallback(name, oldValue, newValue) {
      if (name === 'data-content') {
        this.shadowRoot.getElementById('content').textContent = newValue;
      }
    }
  
    set content(value) {
      this.setAttribute('data-content', value);
    }
  
    get content() {
      return this.getAttribute('data-content');
    }
  }
  
  customElements.define('attribute-element', AttributeElement);

  function buttonClicked() {
    alert('button clicked!');
    const ourCustomElement = document.getElementById('element');
    ourCustomElement.content = 'New content';
  }
</script>

Ici, l'attribute-element met à jour son contenu en fonction de l'attribut data-content. La propriété content offre un moyen pratique de lire et de définir cet attribut de manière programmatique.

Étendre les éléments intégrés

Les éléments personnalisés peuvent étendre les éléments HTML intégrés, ajoutant de nouvelles fonctionnalités tout en conservant leur comportement d'origine.

Exemple : Étendre un élément intégré


javascript
<button is="fancy-button">Click me!</button>
<script>
  class FancyButton extends HTMLButtonElement {
    constructor() {
      super();
      this.addEventListener('click', () => {
        alert('Fancy button clicked!');
      });
    }
  }
  
  customElements.define('fancy-button', FancyButton, { extends: 'button' });
</script>

Ici, fancy-button étend l'élément standard <button>, en ajoutant un message d'alerte lorsque le bouton est cliqué.

Bonnes pratiques pour les éléments personnalisés

  1. Utiliser le Shadow DOM : Encapsulez toujours la structure interne et les styles de votre élément personnalisé à l'aide du Shadow DOM.
  2. Définir des APIs claires : Fournissez des APIs claires et intuitives pour vos éléments personnalisés grâce à des attributs et propriétés bien documentés.
  3. Gestion du cycle de vie : Gérez correctement les callbacks du cycle de vie de l'élément pour garantir un comportement robuste et éviter les fuites de mémoire.
  4. Accessibilité : Assurez-vous que vos éléments personnalisés sont accessibles en incluant les rôles et propriétés ARIA appropriés.
  5. Tests : Testez rigoureusement vos éléments personnalisés sur différents navigateurs et environnements pour garantir la compatibilité et la stabilité.

Conclusion

Les éléments personnalisés offrent un moyen puissant d'étendre HTML, permettant la création de composants réutilisables et encapsulés avec un comportement personnalisé. En exploitant les fonctionnalités des éléments personnalisés, y compris les callbacks du cycle de vie, les attributs, les propriétés et le Shadow DOM, les développeurs peuvent construire des applications web sophistiquées et maintenables.

Commencez à expérimenter les éléments personnalisés dans vos projets dès aujourd'hui et débloquez de nouvelles possibilités pour le développement web. Les exemples fournis ici ne sont que le début : utilisez-les comme base pour créer vos propres éléments personnalisés innovants.

Pratique

Parmi les affirmations suivantes concernant les éléments personnalisés en JavaScript, lesquelles sont vraies ?

Trouvez-vous cela utile?

Aperçu dual-run — comparez avec les routes Symfony en production.