Substituindo uma tag html por outra tag usando o JS DOM
-
19-09-2019 - |
Pergunta
Sou bastante novo no JavaScript e Dom e estou tendo um problema em manipular o DOM usando o JavaScript para o código HTML a seguir.
<html>
<head>
<title>Testing</title>
</head>
<body>
<marquee direction=up height=400 scrollAmount=3.7 scrollDelay=70 onmousedown="this.stop()" onmouseover="this.stop()" onmousemove="this.stop()" onmouseout="this.start()">
<a href="#"> <span>Lion</span></a><br><br>
<a href="#"> <span>Tiger</span></a><br><br>
<a href="#"> <span>Giraffe</span></a><br><br>
<a href="#"> <span>Dinosaur</span></a><br><br>
<a href="#"> <span>Cat</span></a><br><br>
<a href="#"> <span>Dog</span></a><br><br>
<a href="#"> <span>Llama</span></a><br><br>
<a href="#"> <span>Rat</span></a><br><br>
<a href="#"> <span>Rhino</span></a><br><br>
<a href="#"> <span>Reindeer</span></a><br><br>
<a href="#" ><span >buffalo</span></a><br><br>
<a href="#" ><span >Yak</span></a><br><br>
<a href="#" ><span >Deer</span></a><br><br>
<a href="#" ><span >moose</span></a><br><br>
<a href="#" ><span >Rabbit</span></a> <br><br>
<a href="#" ><span >Duck</span></a> <br><br>
<a href="#" ><span >Peacock</span></a><br><br>
<a href="#" ><span >Crow</span></a><br><br>
<a href="#" ><span >Raven</span></a><br><br>
<a href="#" ><span >Swan</span></a><br><br>
</marquee>
<input type="button" value="Set Me Fixed" onclick="setMeFixed();" />
</body>
</html>
Desculpe se o código HTML acima é ruim. Estou escrevendo um script Greasemonkey para o mesmo que é produzido por um site que simplifiquei aqui. Portanto, não tenho controle sobre isso. Eu quero que a tag [letada] seja substituída pela tag [div] para que ela se torne estática e não preciso esperar para sempre pelo 100º link na tenda para aparecer. ;-). Então eu escrevi o seguinte script. (Eu sou novo na programação JS e sim, eu sei que meu script é uma merda :-))
function setMeFixed(){
var fixedElement=document.createElement('div');
var marqueeElement=document.getElementsByTagName('marquee')[0];
//var clonedMarqNodes=marqueeElement.cloneNode(true);
for(i=0;i<marqueeElement.childNodes.length;i++){
fixedElement.appendChild(marqueeElement.childNodes[i]);
}
marqueeElement.parentNode.replaceChild(fixedElement,marqueeElement);
}
Muitos problemas ocorreram. A saída resultante não mostrou poucos links nele. Pavão, corvo, cisne, corvo não são vistos na saída e todo o
As tags são confusas depois que se tornam estáticas com espaços impressos acima e nenhuma quebra entre os links. Como programador de JavaScript iniciante, estou preso aqui e qualquer assistência na direção certa seria muito apreciada. Alguma maneira de resolver elegantemente esse problema? Obrigado.
Paul Bullard.
PS: Estou usando o FX 3.0.11.
Solução
Você já pensou em usar innerhtml?
var marq = document.getElementsByTagName('marquee')[0];
var div = document.createElement('div');
div.innerHTML = marq.innerHTML;
marq.parentNode.appendChild(div);
marq.parentNode.removeChild(marq);
Não é o mais eficiente, mas direto.
Outras dicas
Quanto ao motivo pelo qual seu documento resultante acabou perdendo alguns nós, posso lhe dizer o porquê:
Quando você appendChild
Para outro nó, o DOM o remove de onde quer que fosse. Então, quando você passa pelo primeiro nó, está removendo crianças ao mesmo tempo em que avança i
no DOM. Assuma isso A
, B
, C
, etc. são nós filhos, e é isso que acontece no início do seu loop:
i=0 ↓
MARQUEE: A B C D E F
DIV:
i=1 ↓
MARQUEE: B C D E F
DIV: A
i=2 ↓
MARQUEE: B D E F
DIV: A C
i=3 ↓
MARQUEE: B D F (accessing this gives you an exception!)
DIV: A C E
Você pode consertar isso de duas maneiras. Em primeiro lugar, você pode fazer essa mudança:
fixedElement.appendChild(marqueeElement.childNodes[i]);
// becomes
fixedElement.appendChild(marqueeElement.childNodes[i].cloneNode());
Então você está sempre manipulando um nó clonado e o original <marquee>
Não tem elementos removidos ou você pode fazer essa alteração:
fixedElement.appendChild(marqueeElement.firstChild);
para que você sempre tome o primeiro item no <marquee>
E não perca elementos dessa maneira.
Se seu objetivo é se livrar de <marquee>
está em todos os sites, talvez a melhor maneira de fazer isso é apenas editar seu userContent.css
arquivo para incluir o seguinte:
marquee {
-moz-binding: none; display: block; height: auto !important;
/* This is better than just display:none !important;
* because you can still see the text in the marquee,
* but without scrolling.
*/
}
(Eu acho que isso já está incluído nesse arquivo como modelo, mesmo :)