I can't find examples of vanilla javascript replaceWith
using multiple elements/nodes.
Given HTML with numerous children:
<span id="parent"><span>Hardware:</span> <br>
the <span id="oldChild">physical</span> components of a <span>computer</span>.</span>
Can I use replaceWith
to swap any one of the child
spans, say #oldChild
, with multiple elements AND text nodes (the commas and spaces following these spans):
let newSpans =
"<span id="newChild1">kickable</span>,
<span id="newChild2">throwable</span>,
<span id="newChild3">punchable</span>"
What is wrong with the syntax of the following? And how can I convert this dynamically generated code (above) into an acceptable argument for replaceWith
?
oldChild.replaceWith( newSpans );
Many thanks to Phil, below:
const temp = document.createElement("div")
temp.innerHTML = newSpans
const oldChild = document.getElementById("oldChild")
oldChild.replaceWith(...temp.childNodes)
Note: Phil advises advises wisely it would be preferable to avoid HTML strings.
CodePudding user response:
Can I use
replaceWith
to swap any one of the child spans with multiple elements AND text nodes
The signature for Element.replaceWith() accepts a variable number of Node
or DOMString
arguments...
Syntax
replaceWith(...nodes)
...so, yes
// helper / utility function
const createSpan = (id, textContent) => Object.assign(document.createElement("span"), { id, textContent })
document.getElementById("oldChild").replaceWith(
createSpan("newChild1", "kickable"), // Node
", ", // DOMString
createSpan("newChild2", "throwable"), // Node
", ", // DOMString
createSpan("newChild3", "punchable") // Node
)
#newChild1 { color: green; }
#newChild2 { color: orange; }
#newChild3 { color: red; }
<span id="parent"><span>Hardware:</span> <br> the <span id="oldChild">physical</span> components of a <span>computer</span>.</span>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You could also build up an array of nodes to pass to replaceWith
and use spread syntax
const newSpans = [
createSpan("newChild1", "kickable"),
createSpan("newChild2", "throwable"),
createSpan("newChild3", "punchable")
]
// Add in separators
const newNodes = newSpans.flatMap(s => [s, ", "]).slice(0, -1)
document.getElementById("oldChild").replaceWith(...newNodes) // spread
If all you've got is a string containing HTML, you can...
- Create a temporary element
- Set the
innerHTML
- Pass that element's child nodes to
replaceWith
let newSpans =
`<span id="newChild1">kickable</span>,
<span id="newChild2">throwable</span>,
<span id="newChild3">punchable</span>`
const tmp = document.createElement("div")
tmp.innerHTML = newSpans
document.getElementById("oldChild").replaceWith(...tmp.childNodes)
#newChild1 { color: green; }
#newChild2 { color: orange; }
#newChild3 { color: red; }
/* just showing that #oldChild and the <div> aren't included */
#oldChild, div { background: red; }
<span id="parent"><span>Hardware:</span> <br> the <span id="oldChild">physical</span> components of a <span>computer</span>.</span>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>