Como substituir o elemento DOM no lugar usando Javascript?

162

Eu estou olhando para substituir um elemento no DOM.
Por exemplo, há um <a>elemento que eu quero substituir por um <span>.

Como eu faria isso?

AMD
fonte
9
target.replaceWith(element);é o (ES5 +) forma moderna de fazer isso
Gibolt
2
@ Gibib O que as especificações do DOM têm com o ES? Além disso, ainda não faz parte do padrão DOM, enquanto o ES5 foi lançado há 9 anos.
pishpish
ES5 + significa ES5 OU MAIS TARDE. Mesmo que o ES5 tenha 9 anos, as versões posteriores NÃO são tão antigas.
23918 JustinCB
Se você ainda usa o StackOverflow, vale a pena escolher a nova resposta padrão abaixo.
Mikemaccana

Respostas:

202

usando 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>
Bjorn
fonte
7
este exemplo não funcionaria. Você deve colocar o bloco de scripts no final do corpo para fazê-lo funcionar. Além disso, apenas por diversão: tente adicionar a linha [alert (myAnchor.innerHTML)] após a operação.
1060 KooiInc
Há um erro de ortografia com StackOverflow na âncora innerText
Rahul
8
o que se é elemento html raiz
lisak
Obrigado @Bjorn Tipling. Eu criei um acompanhamento pergunta sobre como adicionar um id e uma função para o elemento substituído, aqui: stackoverflow.com/questions/15670261/...
JDelage
65
var a = A.parentNode.replaceChild(document.createElement("span"), A);

a é o elemento A substituído.

Kamarey
fonte
1
Resposta de @Bjorn Tipling na verdade não funciona. Esta é a resposta (correta!) Para o comentário KooiInc, também correto. Agora funciona! ;-) Tx para ambos!
Pedro Ferreira
4
certamente você poderia ter vindo acima com um nome de variável diferente de A lol
quemeful
61

A.replaceWith(span) - Nenhum pai é necessário

Forma genérica:

target.replaceWith(element);

Muito melhor / mais limpo que o método anterior.

Para o seu caso de uso:

A.replaceWith(span);

Documentos do Mozilla

Navegadores suportados - 94% abr 2020

Gibolt
fonte
13
Não há suporte no IE11 ou no Edge 14 (agora: 16/11/2016).
jor
3
Tente usar o Google Closure ou outro transpiler para converter para o ES5. Você não deveria estar escrevendo código antigo baseado em suporte ao navegador, se você tem uma opção melhor, mais sustentável
Gibolt
1
Transpilando assim. Você pode otimizar, minificar e converter tudo em um. Confira: developers.google.com/closure/compiler
Gibolt
4
Acho que se a opção for entre usar código que funcione em todos os navegadores que estou tentando oferecer suporte ou reprocessar todo o processo de compilação para usar o Closure, eu escolheria o código que funcione em todos os navegadores que estou tentando oferecer suporte .
Cdmckay 16/03
5
Eu concordo em apoiar o maior número possível de navegadores, mas me recuso a refazer o meu código apenas porque o IE ou o Edge estão incompletos ou apenas "querem ser diferentes". Existem padrões, se eles não os seguem e algumas pessoas o apóiam, esse é o problema deles, que não precisa nos afetar como desenvolvedores da web.
David Tabernero M.
4

Essa pergunta é muito antiga, mas eu me encontrei estudando para uma Certificação Microsoft e, no livro de estudo, foi sugerido o uso:

oldElement.replaceNode(newElement)

Eu procurei e parece ser suportado apenas no IE. Doh ..

Eu pensei em adicioná-lo aqui como uma nota lateral engraçada;)

Zeliax
fonte
2

Eu tive um problema semelhante e encontrei este tópico. Substituir não funcionou para mim, e passar pelos pais foi difícil para a minha situação. O Html interno substituiu as crianças, o que também não era o que eu queria. O uso do outerHTML fez o trabalho. Espero que isso ajude alguém!

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

Você pode substituir um nó usando Node.replaceWith(newNode).

Este exemplo deve manter todos os atributos e filhos do nó de origem:

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)
})
Nurul Huda
fonte
-1

Exemplo para substituir elementos LI

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);
    }
}
Kirill
fonte
-1

Dadas as opções já propostas, a solução mais fácil sem encontrar um pai:

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