This package contains the following DOM utilities used in other packages:
bindView(iterator, action, options)
- creates and returns a DOM element which is updated each time when the given iterator returns a new valuegetElementInvalidation(element)
- returns a Promise instance associated with the given DOM element; the returned promise is resolved when the element is removed from the DOM treereplaceDomContent(element, node)
- replaces the content of the given DOM element by the given DOM node (element or text node).trackDomNode(node, { onAdd, onRemove, getContainer })
- tracks the node and calls the specified onAdd/onRemove methods when the node is attached/removed from the DOMtoDomNode(value, doc)
- transforms the given JavaScript value to a DOM node; text, numbers and boolean values are tranformed to Text instances; objects are serialized (with the JSON.stringify method) and also transformed to Text instances; DOM nodes are returned "as is", without modifications.
This method returns a Promise instance associated with the given DOM element; the returned promise is resolved when the element is removed from the DOM tree.
This method returns a single Promise instance for the specific DOM element. This Promise is stored in the invalidation
field of the element.
const div = document.createElement("div");
document.body.appendChild(div);
// Get the invalidation promise associated with the given element:
const invalidation = getElementInvalidation(div);
...
// This function is called when the DOM element is detached from the DOM tree:
const onDetach = () => console.log('The element was detached from DOM...');
invalidation.then(onDetach);
// Check that the second time this method returns the same invalidation instance:
const invalidation2 = getElementInvalidation(div);
assert(invalidation === invalidation2);
// Shows this message:
// 'The element was detached from DOM...'
This utility function allows to update HTML elements when the specified iterator yields a new value. It also allows to easily initialize the element and cleanup associated resources when this element is detached from DOM.
const elm: Element = bindView(
// Async iterator returning new values to visualize:
iterator : AsyncIterator,
// The function returning the element
action : Function,
// Optional parameters:
options : Object = {
// Function used to handle errors
handleError = console.error,
// This function returns the root element to listen
getRoot
} : object = {}
)
The action(...)
callback method recieves the following structure:
params
: parameters objectparams.init
- sets the initialization function; it is called when the view is attached to the DOMparams.done
- sets the finalization function which is called when the view is removed from the DOMparams.update
- sets a new function to call on each value update; the function defined with theupdate
method has the following signature:(view, value, oldValue) => { ... }
Example 1: in this example the activation method registers only one method to init/done/update the created view.
import { bindView } from '@statewalker/utils-dom'
// Generate a new sequence of values to update
// (see below for the implementation of the "generateValues" method):
const it = generateValues(50, 2000);
// Create a new view to append to the document.
const view = bindView(it, ({ init, update, done }) => {
// View initialization:
init((view) => view.innerHTML = "Initializing...");
// Destroys the view and cleans up all associated resources:
done((view) => view.innerHTML = "Destroying...");
// This method is called each time when the iterator returns a new value:
update((view, value, oldValue) => {
view.innerText = `Counter: ${value}!`;
})
// Create and returns the view to update:
return document.createElement("div");
})
// Append the resulting view to the document:
document.body.appendChild(view);
Example 2: in this example the activation method registers two methods for each of the "init/done/update" stages:
import { bindView } from '@statewalker/utils-dom'
// Generate a new sequence of values to update:
// (see below for the implementation of the "generateValues" method):
const it = generateValues(50, 2000);
// In this example the activation function registers two callbacks
// for each of the "init/update/done" stages:
// - one method changes the conntent of the view
// - the second method prints some messages in the log
const div = bindView(it, ({ init, update, done }) => {
// View initialization:
init((view) => view.innerHTML = "Initializing...");
// The second function to call on the view initialization:
init(() => console.log("Init."))
// Destroys the view and cleans up all associated resources:
done((view) => view.innerHTML = "Destroying...");
// The second method to call on initialization:
done(() => console.log("Done."))
// This method is called each time when the iterator returns a new value:
update((view, value, oldValue) => {
view.innerText = `Counter: ${value}!`;
})
// Print the values returned by the iterator:
done((view, newValue, oldValue) => console.log("- Update:", { oldValue, newValue }));
// Create and returns the view to update:
return document.createElement("div");
})
// Append the resulting view to the document:
document.body.appendChild(div);
The generateValues
method used in the examples above:
// This function generates values used to update the view
async function* generateValues(count = 100, maxTimeout = 1000) {
for (let i = 0; i < count; i++) {
yield i;
await new Promise(r => setTimeout(Math.random() * maxTimeout));
}
}
This method replaces the content of the given DOM element by the given DOM node (element or text node).
Example:
import { replaceDomContent } from '@statewalker/utils-dom'
const root = document.querySelector("#root");
const div = document.createElement("div");
div.innerText = 'Hello, world';
replaceDomContent(root, div);
## trackDomNode(node, { onAdd, onRemove, getContainer })
This method tracks the node and calls the specified onAdd/onRemove methods when the node is attached/removed from the DOM.
Parameters:
node
- the DOM node to trackparams
- an object containing method parametersparams.onAdd
- an optional callback method invoked after the node is attached to DOM; it takes the node as the single parameterparams.onRemove
- an optional callback method invoked when the node is removed from DOM; it recieves two parameters: the node itself and a boolean flag showing if the node was notified as attached or not (if the onAdd method was called before)params.getContainer
- returns the container to track for the specified node
This method transforms the given JavaScript value to a DOM node; text, numbers and boolean values are tranformed to Text instances; objects are serialized (with the JSON.stringify method) and also transformed to Text instances; DOM nodes are returned "as is", without modifications.
Example:
import { toDomNode } from '@statewalker/utils-dom'
const root = document.querySelector("#root");
// Transforms string a Text instance:
root.appendChild(toDomNode("Hello, world"))
// Transforms the given number to a Text instance:
root.appendChild(toDomNode(12345))
// Returnes the DOM node without modifications:
const h3 = toDomNode(document.createElement("h3"));
h3.innerHTML = "Hello, there!"
root.appendChild(h3)