import { tryOnScopeDispose } from './tryOnScopeDispose'; import { watch } from 'vue'; import type { MaybeElementRef } from './unrefElement'; import { unrefElement } from './unrefElement'; import { useSupported } from './useSupported'; import type { ConfigurableWindow } from './_configurable'; import { defaultWindow } from './_configurable'; export interface UseMutationObserverOptions extends MutationObserverInit, ConfigurableWindow {} /** * Watch for changes being made to the DOM tree. * * @see https://vueuse.org/useMutationObserver * @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver MutationObserver MDN * @param target * @param callback * @param options */ export function useMutationObserver( target: MaybeElementRef, callback: MutationCallback, options: UseMutationObserverOptions = {}, ) { const { window = defaultWindow, ...mutationOptions } = options; let observer: MutationObserver | undefined; const isSupported = useSupported(() => window && 'MutationObserver' in window); const cleanup = () => { if (observer) { observer.disconnect(); observer = undefined; } }; const stopWatch = watch( () => unrefElement(target), el => { cleanup(); if (isSupported.value && window && el) { observer = new MutationObserver(callback); observer!.observe(el, mutationOptions); } }, { immediate: true }, ); const stop = () => { cleanup(); stopWatch(); }; tryOnScopeDispose(stop); return { isSupported, stop, }; } export type UseMutationObserverReturn = ReturnType;