ResizeObserver
vous indique quand la taille d'un élément change.
Avant ResizeObserver
, vous deviez associer un écouteur au resize
du document
pour être averti de toute modification des dimensions de la fenêtre d'affichage. Dans l'événement
vous devez déterminer quels éléments ont été affectés par
qui changent et appellent une routine
spécifique pour réagir de manière appropriée. Si vous en avez besoin
les nouvelles dimensions d'un élément après un redimensionnement, vous deviez appeler
getBoundingClientRect()
ou getComputedStyle()
, ce qui peut entraîner une mise en page
le thrashing si vous ne vous occupez pas de regrouper toutes vos lectures et toutes vos
les opérations d'écriture.
Cela ne concernait même pas les cas où les éléments changent de taille sans
fenêtre ayant été redimensionnée. Par exemple, ajouter de nouveaux enfants, définir une
le style display
de l'élément en none
, ou des actions similaires peuvent modifier la taille de
d'un élément, de ses frères ou sœurs ou de ses ancêtres.
C'est pourquoi la primitive ResizeObserver
est utile. Il réagit aux changements
taille des éléments observés, indépendamment de la cause du changement.
Elle permet également d'accéder à la nouvelle taille des éléments observés.
Navigateurs pris en charge
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
API
Toutes les API avec le suffixe Observer
que nous avons mentionnées ci-dessus partagent une API simple
la conception. ResizeObserver
ne fait pas exception. Vous créez un objet ResizeObserver
.
et transmettre un rappel au constructeur. Le rappel reçoit un tableau de
des objets ResizeObserverEntry
(une entrée par élément observé), qui
contient les nouvelles dimensions de l'élément.
var ro = new ResizeObserver(entries => {
for (let entry of entries) {
const cr = entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${cr.width}px x ${cr.height}px`);
console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
}
});
// Observe one or multiple elements
ro.observe(someElement);
Quelques informations
Quels sont les éléments signalés ?
En général, un
ResizeObserverEntry
signale la zone de contenu d'un élément via une propriété appelée
contentRect
, qui renvoie un
DOMRectReadOnly
. La zone de contenu est la zone dans laquelle le contenu peut être placé. Il est
la zone de bordure moins la marge intérieure.
Il est important de noter que si ResizeObserver
rapporte à la fois les dimensions
du contentRect
et de la marge intérieure, il surveille uniquement contentRect
.
Ne confondez pas contentRect
avec le cadre de délimitation de l'élément. La limite
comme indiqué par getBoundingClientRect()
, est la boîte qui contient le
l'élément entier et ses descendants. Les fichiers SVG font exception à la règle, car
ResizeObserver
indique les dimensions du cadre de délimitation.
Depuis Chrome 84, ResizeObserverEntry
possède trois nouvelles propriétés pour offrir plus
des informations détaillées. Chacune de ces propriétés renvoie un ResizeObserverSize
contenant une propriété blockSize
et une propriété inlineSize
. Ce
Les informations concernent l'élément observé au moment où le rappel est invoqué.
borderBoxSize
contentBoxSize
devicePixelContentBoxSize
Tous ces éléments renvoient des tableaux en lecture seule, ils peuvent prendre en charge des éléments comportant plusieurs fragments, qui apparaissent dans à plusieurs colonnes. Pour l'instant, ces tableaux ne contiennent qu'un seul élément.
La prise en charge de ces propriétés par la plate-forme est limitée, mais Firefox compatible avec les deux premières.
Quand est-elle signalée ?
La spécification interdit que ResizeObserver
traite tous les événements de redimensionnement
avant la peinture et après la mise en page. Ainsi, le rappel d'un ResizeObserver
devient le
l'endroit idéal pour modifier la mise en page de votre page. Parce que ResizeObserver
entre la mise en page et la peinture, cela n'invalide
la mise en page, pas la peinture.
J'ai compris
Vous vous demandez peut-être ce qui se passe si je modifie la taille d'une vue observée.
dans le rappel de ResizeObserver
? La réponse est: vous allez déclencher
un autre appel au rappel. Heureusement, ResizeObserver
a un
pour éviter les boucles de rappel infinies et les dépendances cycliques. Les modifications
ne seront traités dans le même cadre que si l'élément redimensionné est plus profondément dans le DOM
que l'élément le plus superficiel traité dans le rappel précédent.
Sinon, elles seront différées vers l'image suivante.
Application
ResizeObserver
vous permet d'implémenter un élément par élément.
des requêtes média. En observant les éléments, vous pouvez définir de manière impérative votre
concevoir des points d’arrêt
et modifier les styles d’un élément. Dans les
exemple : le deuxième champ
modifie l'arrondi de sa bordure en fonction de sa largeur.
const ro = new ResizeObserver(entries => {
for (let entry of entries) {
entry.target.style.borderRadius =
Math.max(0, 250 - entry.contentRect.width) + 'px';
}
});
// Only observe the second box
ro.observe(document.querySelector('.box:nth-child(2)'));
Autre exemple intéressant : la fenêtre de chat. Le problème qui se pose dans une mise en page de conversation typique de haut en bas est le positionnement du défilement. Pour éviter déconcerter l'utilisateur, il est utile que la fenêtre soit collée au bas de la fenêtre où s'affichent les derniers messages. De plus, tout type de mise en page (pensez à un téléphone qui passe du mode paysage au mode portrait, ou inversement). atteindre le même résultat.
ResizeObserver
vous permet d'écrire un seul extrait de code qui se charge de
les deux scénarios. Le redimensionnement de la fenêtre est un événement qu'un ResizeObserver
peut
capture par définition, mais appeler appendChild()
redimensionne également cet élément
(sauf si overflow: hidden
est défini), car il doit libérer de l'espace pour les nouvelles
éléments. C'est pourquoi il faut très peu de lignes pour atteindre l'objectif
effet:
const ro = new ResizeObserver(entries => {
document.scrollingElement.scrollTop =
document.scrollingElement.scrollHeight;
});
// Observe the scrollingElement for when the window gets resized
ro.observe(document.scrollingElement);
// Observe the timeline to process new messages
ro.observe(timeline);
Plutôt sympa, non ?
À partir de là, je pourrais ajouter plus de code pour gérer le cas où l'utilisateur a fait défiler la page manuellement et que vous voulez vous en tenir à ce message lorsqu'un nouveau message entre en jeu.
Autre cas d'utilisation : tout type d'élément personnalisé utilisant sa propre mise en page.
Avant le ResizeObserver
, il n'existait aucun moyen fiable d'être notifié lorsque
les dimensions changent afin que ses enfants puissent être disposés à nouveau.
Effets sur l'interaction avec la peinture suivante (INP)
L'Interaction to Next Paint (INP) est une métrique qui mesure la la réactivité globale d'une page aux interactions de l'utilisateur. Si l'INP d'une page se trouve dans les "bonnes" seuil, soit 200 de millisecondes ou moins. On peut dire qu'une page réagit de façon fiable les interactions de l'utilisateur avec elle.
Alors que le temps nécessaire aux rappels d'événement pour s'exécuter en réponse à une l'interaction utilisateur peut contribuer de manière significative à la latence totale d'une interaction, ce n'est pas le seul aspect d'INP à prendre en compte. INP tient également compte de la quantité de temps nécessaire pour que la prochaine peinture de l'interaction se produise. Il s'agit de la temps nécessaire au rendu nécessaire pour mettre à jour l'utilisateur interface en réponse à une interaction pour terminer.
En ce qui concerne ResizeObserver
, c'est important, car le rappel qui
une instance ResizerObserver
s'exécute juste avant le rendu. Ce
ce qui est prévu par la conception, car le travail effectué lors du rappel doit être traité
ce travail nécessitera très probablement de modifier
de l'interface utilisateur.
Assurez-vous d'effectuer aussi peu de tâches d'affichage que nécessaire dans un ResizeObserver
.
, car un rendu excessif peut entraîner des situations dans lesquelles le navigateur
a du retard dans ses tâches importantes. Par exemple, si une interaction a
qui entraîne l'exécution d'un rappel ResizeObserver
, assurez-vous d'effectuer la
pour que l'expérience soit la plus fluide possible:
- Assurez-vous que vos sélecteurs CSS sont aussi simples que possible afin d'éviter le recalcul des styles est trop important. Les recalculs de style ont lieu juste avant la mise en page, et les sélecteurs CSS complexes retarder les opérations de mise en page.
- Évitez d'effectuer des tâches dans votre rappel
ResizeObserver
qui peuvent déclencher ajustements forcés de la mise en page. - Le temps nécessaire pour mettre à jour la mise en page d'une page augmente généralement avec le
le nombre d'éléments DOM sur une page. Bien que cela soit vrai, que les pages utilisent ou non
ResizeObserver
, le travail effectué dans un rappelResizeObserver
peut devenir à mesure que la complexité structurelle d'une page augmente.
Conclusion
ResizeObserver
est disponible dans toutes les principales
navigateurs
et permet de surveiller efficacement les redimensionnements d'éléments au niveau d'un élément
d'application. Veillez simplement à ne pas trop retarder l'affichage avec cette API puissante.