Wenn MutationObserver mehrfach eingerichtet wird, können doppelte Observer auf demselben Element registriert werden. Eine Verwaltung über ein globales Set oder Map ist möglich, aber das Schreiben eines Beobachtet-Flags in dataset ist leichtgewichtig und leicht portierbar.
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 }}Verwendung
// Akzeptiert sowohl einen Selektor-String als auch ein HTMLElementobserveElement( 'my-list-observer', '#item-list', (mutations) => { for (const mutation of mutations) { console.log('Änderung erkannt:', mutation.type) } })
// Ein erneuter Aufruf auf demselben Element registriert keinen doppelten ObserverobserveElement('my-list-observer', '#item-list', callback)Funktionsweise
Object.hasOwn(ele.dataset, OBSERVE_ID_KEY)prüft das Vorhandensein desdata-observe-id-Attributs- Nur wenn noch nicht registriert, wird ein
MutationObservererstellt undobserve()aufgerufen - Nach dem Start der Beobachtung wird das Flag über
ele.dataset[OBSERVE_ID_KEY] = idgesetzt - Bei nachfolgenden Aufrufen gibt
isElementObservedtruezurück und es passiert nichts
Da dataset-Werte direkt in das HTML-data-*-Attribut geschrieben werden, sind sie in den DevTools sichtbar.
Vorteile
- Kein globales Registry: Der Zustand wird im Element selbst gespeichert, sodass keine separate
MapoderSetverwaltet werden muss - Hochgradig portierbar: Keine Framework-Abhängigkeiten; funktioniert in jeder Umgebung
- Leicht debuggbar: Attributwerte können direkt in den DevTools überprüft werden
Hinweise
Wenn ein Element aus dem DOM entfernt wird, gehen die dataset-Informationen verloren. Wird dasselbe Element erneut eingefügt, wird wieder ein Observer registriert. Zum Stoppen eines Observers muss zudem observer.disconnect() separat aufgerufen werden.
hsb.horse