gracefullyReplaceNode
gracefullyReplaceNode swaps one element in the DOM for another while preserving the user's experience. It's designed for section rendering / AJAX updates where you replace a chunk of markup with a freshly rendered version.
It does more than a plain oldNode.replaceWith(newNode):
- Preserves focus — if a form control (input or select) was focused before the swap, it does its best to restore focus (and the selected value) to the equivalent control in the new markup, using
id, thenname, thenname+value. - Re-executes scripts —
<script>tags set viainnerHTMLdon't run by default, so it re-injects any scripts in the new content so they execute. - Runs callbacks — you can pass arrays of callbacks to run just before and just after the replacement.
It accepts:
| Argument | Type | Default | Description |
|---|---|---|---|
oldNode | Element | — | The element currently in the DOM that you want to replace. |
newContent | Element | — | The new element to put in its place. |
preReplaceCallbacks | Array<Function> | [] | Callbacks run with the new content before the swap. |
postReplaceCallbacks | Array<Function> | [] | Callbacks run with the newly inserted node after the swap. |
Usage examples
Basic
- 2.0 Build
- 1.0 Build
// Fetch a re-rendered section and swap it in
const html = await window.BAO.utils.fetchJSON(
`${window.location.pathname}?section_id=cart-items`,
)
const parsed = new DOMParser().parseFromString(html, 'text/html')
const newNode = window.BAO.utils.getElement('.crt-Items', { context: parsed })
const oldNode = window.BAO.utils.getElement('.crt-Items')
window.BAO.utils.gracefullyReplaceNode(oldNode, newNode)
// Fetch a re-rendered section and swap it in
const html = await fetchJSON(`${window.location.pathname}?section_id=cart-items`)
const parsed = new DOMParser().parseFromString(html, 'text/html')
const newNode = getElement('.crt-Items', { context: parsed })
const oldNode = getElement('.crt-Items')
gracefullyReplaceNode(oldNode, newNode)
With pre/post callbacks
- 2.0 Build
- 1.0 Build
window.BAO.utils.gracefullyReplaceNode(
oldNode,
newNode,
[(node) => node.classList.add('is-loading')],
[(node) => node.classList.remove('is-loading')],
)
gracefullyReplaceNode(
oldNode,
newNode,
[(node) => node.classList.add('is-loading')],
[(node) => node.classList.remove('is-loading')],
)