Lorsque MutationObserver est configuré plusieurs fois, des observateurs en double peuvent être enregistrés sur le même élément. Gérer cela avec un Set ou une Map global est possible, mais écrire un flag d’observation dans dataset est léger et facile à porter.
Code
const OBSERVE_ID_KEY = 'observeId'
const isElementObserved = <T extends HTMLElement = HTMLElement>( ele: T) => Object.hasOwn(ele.dataset, OBSERVE_ID_KEY)
const setObserverId = (id: string) => <T extends HTMLElement = HTMLElement>(ele: T): T => { ele.dataset[OBSERVE_ID_KEY] = id return ele }
export const observeElement = ( observeId: string, element: HTMLElement | string, observerCallback: MutationCallback, options: MutationObserverInit = { childList: true }) => { const observedElement = element instanceof HTMLElement ? element : document.querySelector<HTMLElement>(element) if (observedElement && !isElementObserved(observedElement)) { const observer = new MutationObserver(observerCallback) observer.observe(observedElement, options) setObserverId(observeId)(observedElement) return observer }}Utilisation
// Accepte un sélecteur CSS ou un HTMLElementobserveElement( 'my-list-observer', '#item-list', (mutations) => { for (const mutation of mutations) { console.log('Changement détecté :', mutation.type) } })
// Appeler à nouveau sur le même élément ne crée pas de doublonobserveElement('my-list-observer', '#item-list', callback)Fonctionnement
Object.hasOwn(ele.dataset, OBSERVE_ID_KEY)vérifie la présence de l’attributdata-observe-id- Seulement si non enregistré, un
MutationObserverest créé etobserve()est appelé - Après le démarrage de l’observation, le flag est écrit via
ele.dataset[OBSERVE_ID_KEY] = id - Lors des appels suivants,
isElementObservedrenvoietrueet rien ne se passe
Les valeurs de dataset étant écrites directement dans l’attribut HTML data-*, elles sont visibles dans les DevTools.
Avantages
- Pas de registre global : L’état est stocké dans l’élément lui-même, éliminant le besoin de gérer une
Mapou unSetséparé - Très portable : Aucune dépendance à un framework ; fonctionne dans n’importe quel environnement
- Facile à déboguer : Les valeurs des attributs peuvent être inspectées directement dans les DevTools
Points d’attention
Lorsqu’un élément est supprimé du DOM, ses informations dataset sont également perdues. Si le même élément est réinséré, un observateur sera à nouveau enregistré. De plus, pour arrêter un observateur, il faut appeler observer.disconnect() séparément.
hsb.horse