Aller au contenu

Shadow DOM et Événements

Bienvenue dans notre guide pour maîtriser la gestion des événements dans le Shadow DOM. Ce tutoriel couvre des concepts essentiels tels que la propagation des événements (bubbling), event.composedPath(), event.composed et les événements personnalisés. À la fin, vous saurez comment gérer efficacement les événements au sein des composants Shadow DOM.

Propagation des événements dans le Shadow DOM

La propagation des événements (bubbling) est un mécanisme fondamental en JavaScript qui décrit comment les événements se propagent à travers la hiérarchie du DOM. Lorsqu'un événement se produit sur un élément DOM, il déclenche d'abord les gestionnaires d'événements attachés à cet élément, puis se propage à ses ancêtres, déclenchant leurs gestionnaires d'événements séquentiellement.

Dans le contexte du Shadow DOM, la propagation des événements se comporte légèrement différemment. Par défaut, la plupart des événements natifs (comme click ou mouseover) sont composés et traversent la limite du shadow DOM. Cependant, certains événements (comme focus ou scroll) ne sont pas composés et restent contenus à l'intérieur du shadow DOM. Les événements personnalisés nécessitent une configuration explicite pour franchir cette limite. Pour arrêter complètement la propagation à tout moment, vous pouvez utiliser event.stopPropagation().

Utilisation de event.composedPath()

La méthode event.composedPath() permet de récupérer la séquence des éléments DOM qu'un événement traverse lors de sa propagation, y compris les éléments à l'intérieur du Shadow DOM. Cette méthode retourne un tableau de nœuds DOM représentant le chemin de l'événement, permettant aux développeurs d'inspecter et de manipuler le flux de propagation.

Illustrons comment event.composedPath() peut être utilisé pour suivre la propagation des événements dans le Shadow DOM :


html
<div id="outer"></div>
<script>
  const outer = document.getElementById('outer');
  const shadow = outer.attachShadow({ mode: 'open' });
  const inner = document.createElement('div');
  inner.textContent = 'Click me';

  inner.addEventListener('click', event => {
    const composedInfo = document.createElement('p');
    composedInfo.textContent = 'The event composedPath contains the following elements:';
    shadow.appendChild(composedInfo);
    const path = event.composedPath();
    path.forEach((e) => {
      const pathItem = document.createElement('p');
      pathItem.textContent = e.tagName;
      shadow.appendChild(pathItem);
    });
  });

  shadow.appendChild(inner);
</script>

Dans cet exemple, un clic sur le <div> interne déclenche le gestionnaire d'événements click qui lui est attaché. Nous créons dynamiquement quelques éléments <p> pour afficher la réponse de event.composedPath() à l'intérieur du shadow DOM.

Comprendre event.composed

La propriété event.composed indique si un événement est composé ou non. Les événements composés sont capables de traverser les limites du shadow DOM, tandis que les événements non composés restent confinés à l'intérieur de cette limite. Notez que event.composed est une propriété en lecture seule. Cela est particulièrement utile lors de la manipulation d'événements personnalisés, qui nécessitent composed: true dans leurs options pour franchir les limites du shadow DOM, contrairement aux événements natifs comme click qui sont composés par défaut.

Examinons comment event.composed peut être utilisé en pratique :


html
<div id="outer"></div>

<script>
  const outer = document.getElementById('outer');
  const shadow = outer.attachShadow({ mode: 'open' });
  const button = document.createElement('button');
  button.textContent = 'Click me';

  button.addEventListener('click', event => {
    const composedInfo = document.createElement('p');
    composedInfo.textContent = `Composed: ${event.composed}`;
    shadow.appendChild(composedInfo);
  });

  shadow.appendChild(button);
</script>

Dans cet exemple, un clic sur le bouton à l'intérieur du shadow DOM déclenche un événement click. Nous créons dynamiquement un élément <p> pour afficher la propriété event.composed à l'intérieur du shadow DOM.

Événements personnalisés dans le Shadow DOM

Les événements personnalisés permettent aux développeurs de définir et de déclencher leurs propres types d'événements, offrant un mécanisme flexible pour la communication entre composants. Lors de l'utilisation du Shadow DOM, les événements personnalisés peuvent servir à faciliter la communication entre les éléments du shadow DOM et du light DOM, permettant ainsi une interaction fluide au sein de l'application web.

Créons et déclenchons un événement personnalisé à l'intérieur d'un shadow DOM :


html
<div id="container"></div>

<script>
  const container = document.getElementById('container');
  const shadow = container.attachShadow({ mode: 'open' });
  const button = document.createElement('button');
  button.textContent = 'Click me';

  button.addEventListener('click', () => {
    const event = new CustomEvent('customEvent', { bubbles: true, composed: true });
    button.dispatchEvent(event);
  });

  shadow.appendChild(button);

  container.addEventListener('customEvent', () => {
    const composedInfo = document.createElement('p');
    composedInfo.textContent = `Custom Event Triggered!`;
    container.appendChild(composedInfo);
  });
</script>

Dans cet exemple, un clic sur le bouton à l'intérieur du shadow DOM déclenche un événement personnalisé nommé customEvent avec les options bubbles: true et composed: true, lui permettant de se propager à travers les limites du shadow DOM. L'écouteur d'événements est attaché à l'élément hôte (container) dans le light DOM, démontrant comment l'événement franchit la limite du shadow DOM et déclenche le gestionnaire.

Conclusion

Maîtriser la gestion des événements dans le Shadow DOM est essentiel pour construire des applications web robustes. En comprenant la propagation des événements, event.composedPath(), event.composed et les événements personnalisés, vous pourrez gérer efficacement la propagation des événements et permettre une communication fluide entre les composants. Continuez à expérimenter avec ces exemples pour devenir compétent en programmation événementielle au sein du Shadow DOM.

Pratique

Quelle méthode permet de récupérer la séquence des éléments DOM qu'un événement traverse lors de sa propagation ?

Trouvez-vous cela utile?

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