Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am looking to replace an element in the DOM.
For example, there is an <a> element that I want to replace with a <span> instead.

How would I go and do that?

@Gibolt What does DOM spec have with ES? Moreover, it's not yet a part of the DOM standard, while ES5 was released 9 years ago. pishpish Jan 7, 2018 at 13:30 <a id="myAnchor" href="http://www.stackoverflow.com">StackOverflow</a> <script type="text/JavaScript"> var myAnchor = document.getElementById("myAnchor"); var mySpan = document.createElement("span"); mySpan.innerHTML = "replaced anchor!"; myAnchor.parentNode.replaceChild(mySpan, myAnchor); </script> </body> </html> this example wouldn't work. You should put the script block at the end of the body to make it work. Furthermore, just for fun: try adding the line [alert(myAnchor.innerHTML)] after the operation. KooiInc May 10, 2009 at 8:27 Thank you @Bjorn Tipling. I've created a follow up question on how to add an id and a function to the replaced element, here: stackoverflow.com/questions/15670261/… JDelage Mar 27, 2013 at 21:58
  • You can pass multiple values (or use spread operator ... ).
  • Any string value will be added as a text element.
  • Examples:

    // Initially [child1, target, child3]
    target.replaceWith(span, "foo")     // [child1, span, "foo", child3]
    const list = ["bar", span]
    target.replaceWith(...list, "fizz")  // [child1, "bar", span, "fizz", child3]
    

    Safely handling null target

    If your target has a chance to be null, you can consider using the newish ?. optional chaining operator. Nothing will happen if target doesn't exist. Read more here.

    target?.replaceWith?.(element)
    

    Related DOM methods

  • Read More - child.before and child.after
  • Read More - parent.prepend and parent.append
  • Mozilla Docs

    Supported Browsers - 97% Nov '22

    Try using Google's Closure or another transpiler to convert to ES5. You shouldn't be writing old code based on browser support, if you have a better, more maintainable option – Gibolt Jan 12, 2017 at 3:37 I think if the choice is between use code that works on all browsers I'm trying to support, or re-tool your whole build process to use Closure, I would pick use code that works on all browsers that I'm trying to support. – cdmckay Mar 16, 2017 at 2:34 @jor I kinda agree to support as many browsers as possible, but I refuse to remade my code just because IE or Edge are incomplete or just "want to be different". There are standards, if they don't follow them and a few people support it, that is their problem, that don't have to affect us as web developers. – David Tabernero M. Jul 25, 2017 at 11:05 Answer from @Bjorn Tipling in fact does not work. This is the (correct!) answer for KooiInc, also correct, comment . Now it works! ;-) Tx to both! – Pedro Ferreira Jan 16, 2018 at 16:58

    This question is very old, but I found myself studying for a Microsoft Certification, and in the study book it was suggested to use:

    oldElement.replaceNode(newElement)
    

    I looked it up and it seems to only be supported in IE. Doh..

    I thought I'd just add it here as a funny side note ;)

    I had a similar issue and found this thread. Replace didn't work for me, and going by the parent was difficult for my situation. Inner Html replaced the children, which wasn't what I wanted either. Using outerHTML got the job done. Hope this helps someone else!

    currEl = <div>hello</div>
    newElem = <span>Goodbye</span>
    currEl.outerHTML = newElem
    # currEl = <span>Goodbye</span>
    

    You can replace an HTML Element or Node using Node.replaceWith(newNode).

    This example should keep all attributes and childs from origin node:

    const links = document.querySelectorAll('a')
    links.forEach(link => {
      const replacement = document.createElement('span')
      // copy attributes
      for (let i = 0; i < link.attributes.length; i++) {
         const attr = link.attributes[i]
         replacement.setAttribute(attr.name, attr.value)
      // copy content
      replacement.innerHTML = link.innerHTML
      // or you can use appendChild instead
      // link.childNodes.forEach(node => replacement.appendChild(node))
      link.replaceWith(replacement)
    

    If you have these elements:

    <a href="#link-1">Link 1</a>
    <a href="#link-2">Link 2</a>
    <a href="#link-3">Link 3</a>
    <a href="#link-4">Link 4</a>
    

    After running above codes, you will end up with these elements:

    <span href="#link-1">Link 1</span>
    <span href="#link-2">Link 2</span>
    <span href="#link-3">Link 3</span>
    <span href="#link-4">Link 4</span>
                    The answers given assume a static DOM. What if the DOM has been modified, e.g., via an onload script?
    – Page Notes
                    Dec 20, 2020 at 0:48
                    just make sure that the document.querySelectorAll('a') is executed after the DOM has been modified or generated.
    – Nurul Huda
                    Dec 22, 2020 at 15:14
    

    You can use replaceChild on the parent of the target element after creating your new element (createElement):

    const newElement = document.createElement(/*...*/);
    const target = document.getElementById("my-table");
    target.parentNode.replaceChild(newElement, target);
    

    If your starting point for the new element is HTML, you can use insertAdjacentHTML and then removeChild on the parent (or remove on the element itself, in modern environments):

    const target = document.getElementById("my-table");
    target.insertAdjacentHTML("afterend", theHTMLForTheNewElement);
    target.parentNode.removeChild(target); // Or: `target.remove()`
    

    Best way to do it. No parents need. Just use Element.outerHTML = template;

    // Get the current element
    var currentNode = document.querySelector('#greeting');
    // Replace the element
    currentNode.outerHTML =
        '<div id="salutations">' +
            '<h1>Hi, universe!</h1>' +
            '<p>The sun is always shining!</p>' +
        '</div>';
        let li = element.parentElement;
        let ul = li.parentNode;   
        if (li.nextSibling.nodeName === 'LI') {
            let li_replaced = ul.replaceChild(li, li.nextSibling);
            ul.insertBefore(li_replaced, li);
    

    Given the already proposed options the easiest solution without finding a parent:

    var parent = document.createElement("div");
    var child = parent.appendChild(document.createElement("a"));
    var span = document.createElement("span");
    // for IE
    if("replaceNode" in child)
      child.replaceNode(span);
    // for other browsers
    if("replaceWith" in child)
      child.replaceWith(span);
    console.log(parent.outerHTML);
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.