Home > Mobile >  using replaceWith to replace an element with a DOMstring or multiple elements in Vanilla JS
using replaceWith to replace an element with a DOMstring or multiple elements in Vanilla JS

Time:10-25

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...

  1. Create a temporary element
  2. Set the innerHTML
  3. 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>

  • Related