Découverte du ResizeObserver

Voir la vidéo

Quand on a besoin qu'un élément réagisse en fonction de sa dimension en JavaScript, on pense souvent à l'évènement resize (window.addEventListener('resize')). Cependant, saviez vous qu'il existe une API qui permet justement d'observer les changements de taille d'un élément ? Le ResizeObserver. Dans cet article je vous propose de voir ensemble son fonctionnement et les bénéfice de cette approche.

Fonctionnement de base

L’API est très proche de celle de l'IntersectionObserver dans son approche : un observer, un callback, et plusieurs éléments potentiels à surveiller.
Pour observer les changement de taille de nos éléments on commence par créer un observer :

const observer = new ResizeObserver(entries => {
  for (const entry of entries) {
    console.log(entry.borderBoxSize); // Attention borderBoxSize est un tableau
  }
});

Le callback reçoit une liste d’entrées (ResizeObserverEntry), chaque entrée correspond à un élément observé. On peut ensuite utiliser cet observer pour observer un élément

observer.observe(document.getElementById('video'));

Un même observer peut suivre plusieurs éléments. Lorsqu'un élément sera redimensionné on retrouvera plusieurs information importante dans notre ResizeObserverEntry :

  • target, l'élément cible
  • borderBoxSize, un tableau représentant la taille de l'élément (en incluant les marges intérieurs)
  • contentBoxSize, un tableau représentant la taille du contenu de l'élément.

Les 2 valeurs, borderBoxSize et contentBoxSize sont des tableaux pour supporter des éléments composés de plusieurs fragments mais dans la plupart des cas ils auront une taille de 1.

const { inlineSize, blockSize } = entry.borderBoxSize[0];

// inlineSize = largeur
// blockSize = hauteur

⚠️ Même si l’élément passe en display: none, ResizeObserver continue à signaler les changements, avec une taille (0, 0).

Enfin, si on souhaite arrêter d'observer, on peut utiliser les méthodes unobserve() et disconnect()

observer.unobserve(el); // Coupe l'observation pour un élément
observer.disconnect(); // Couper l'observation de tous les éléments

Pourquoi préférer ResizeObserver à window.resize ?

Ecouter l'évènement resize sur window pour observer un changement de taille d'un élement à un gros défaut :

  • On est obligé de vérifier la taille de l'élément getBoundingClientRect() pour savoir si l'élément a changé de taille.
  • Si l'élément est dans un conteneur à largeur fixe, on fera beaucoup d'appel / calcul non nécessaire.

Avec ResizeObserver rien ne se passe tant que l’élément conserve la même dimension ce qui permet d'appeler le callback moins souvent et d'avoir de meilleurs performances.

Attention aux boucles

Attention cependant à ne pas créer une boucle infinie lors de l'utilisation du ResizeObserver. En effet, si dans la logique de votre observer vous transformez les dimensions de l'élément (sa largeur ou sa hauteur) directement ou indirectement le callback peut être re-appeler et ainsi créer une boucle infinie. On essaiera, tant que possible d'éviter ce cas.

Le callback est appelé initialement

Un autre détail important est le fait que le callback du ResizeObserver est appelé lorsqu'un élément est observé.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager