https://github.com/sindresorhus/dom-mutations
Observe changes to the DOM using an async iterable — A nicer API for MutationObserver
https://github.com/sindresorhus/dom-mutations
Last synced: 9 days ago
JSON representation
Observe changes to the DOM using an async iterable — A nicer API for MutationObserver
- Host: GitHub
- URL: https://github.com/sindresorhus/dom-mutations
- Owner: sindresorhus
- License: mit
- Created: 2023-11-21T20:54:12.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-18T07:47:27.000Z (8 months ago)
- Last Synced: 2025-03-30T09:09:32.257Z (16 days ago)
- Language: JavaScript
- Size: 9.77 KB
- Stars: 211
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: license
Awesome Lists containing this project
- jimsghstars - sindresorhus/dom-mutations - Observe changes to the DOM using an async iterable — A nicer API for MutationObserver (JavaScript)
README
# dom-mutations
> Observe changes to the DOM using an async iterable — A nicer API for [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
This package only works in the browser.
## Install
```sh
npm install dom-mutations
```## Usage
```js
import domMutations from 'dom-mutations';const target = document.querySelector('#unicorn');
for await (const mutation of domMutations(target, {childList: true})) {
console.log('Mutation:', mutation);
}
```## API
### domMutations(target, options?) (default export)
Accepts the same arguments as [`MutationObserver#observe()`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#parameters) with an additional optional [`signal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal) option to abort the observation. If the signal is triggered, the async iterable throws an [abort error](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort).
Returns an [`AsyncIterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) that yields [`MutationRecord`](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord) objects representing individual mutations.
### batchedDomMutations(target, options?) (named export)
Similar to `domMutations()`, but yields batches of [`MutationRecord`](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord) objects, each batch representing a group of mutations captured together. This method is less convenient, but can be useful in some cases when you need to handle mutations together as a group.
```js
import {batchedDomMutations} from 'dom-mutations';const target = document.querySelector('#unicorn');
for await (const mutations of batchedDomMutations(target, {childList: true})) {
console.log('Batch of mutations:', mutations);
}
```## FAQ
### How do I stop the iteration?
Simply `return` or `break` in the loop body.
### How do I stop the iteration from the outside?
**Triggering the iterator to return**
```js
import domMutations from 'dom-mutations';const target = document.querySelector('#unicorn');
const mutationIterator = domMutations(target, {childList: true})[Symbol.asyncIterator]();
(async () => {
for await (const mutation of mutationIterator) {
console.log('Mutation:', mutation);
}
})();setTimeout(() => {
mutationIterator.return();
}, 10000);
```**Using a variable**
This has the downside of not ending the iteration until the next mutation.
```js
import domMutations from 'dom-mutations';const target = document.querySelector('#unicorn');
let shouldStop = false;
(async () => {
for await (const mutation of domMutations(target, {childList: true})) {
if (shouldStop) {
break;
}console.log('Mutation:', mutation);
}
})();setTimeout(() => {
shouldStop = true;
}, 10000);
```**Using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)**
Unlike the above approaches, this will make the iterable throw an [abort error](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort).
```js
import domMutations from 'dom-mutations';const target = document.querySelector('#unicorn');
const controller = new AbortController();
const {signal} = controller;(async () => {
for await (const mutation of domMutations(target, {childList: true, signal})) {
console.log('Mutation:', mutation);
}
})();setTimeout(() => {
controller.abort();
}, 10000);
```## Related
- [request-animation-frames](https://github.com/sindresorhus/request-animation-frames) - Use `requestAnimationFrame` as an async iterable, in any JavaScript environment