230

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?

4
  • 20
    target.replaceWith(element); is the modern (ES5+) way to do this Commented Nov 11, 2016 at 7:44
  • 2
    @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. Commented Jan 7, 2018 at 13:30
  • 1
    ES5+ means ES5 OR LATER. Even if ES5 is 9 years old, later versions are NOT that old. Commented Jun 29, 2018 at 13:40
  • If you still use StackOverflow it's worth picking the new standard answer below. Commented Aug 29, 2018 at 18:46

10 Answers 10

231

by using replaceChild():

<html>
<head>
</head>
<body>
  <div>
    <a id="myAnchor" href="http://www.stackoverflow.com">StackOverflow</a>
  </div>
<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>
Sign up to request clarification or add additional context in comments.

4 Comments

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.
Theres a spelling mistake with StackOverflow in the anchor innerText
what if it is root html element
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/…
157

A.replaceWith(span) - No parent needed

Generic form:

target.replaceWith(element)

Way better/cleaner than the previous method.

For your use case:

A.replaceWith(span)

Advanced usage

  1. You can pass multiple values (or use spread operator ...).
  2. 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

  1. Read More - child.before and child.after
  2. Read More - parent.prepend and parent.append

Mozilla Docs

Supported Browsers - 97% Nov '22

12 Comments

Not supported in IE11 or Edge 14 (now: 2016-11-16).
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
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.
@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.
Global support is now at 72%, 80% in U.S. as of Oct 2017
|
68
var a = A.parentNode.replaceChild(document.createElement("span"), A);

a is the replaced A element.

2 Comments

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!
surely you could have come up with a variable name other than A lol
8

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 ;)

Comments

4

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>';

Comments

3

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>

2 Comments

This is very clever but I don't know if it complies to the standards. Thanks !
Probably it is globally used and I vote answer is the best !
3

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>

2 Comments

The answers given assume a static DOM. What if the DOM has been modified, e.g., via an onload script?
just make sure that the document.querySelectorAll('a') is executed after the DOM has been modified or generated.
2

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()`

Comments

-1

Example for replacing LI elements

function (element) {
    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);
    }
}

Comments

-1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.