Question

I am fairly new to javascript and DOM and I am having a problem with manipulating DOM using javascript for the following html code.

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

Sorry if the above html code is bad.I am writing a greasemonkey script for the same which is produced by a site which i have simplified here. So i have no control over it whatsoever. I want the [marquee] tag to be replaced with the [div] tag so that it becomes static and i don't have to wait forever for the 100th link in the marquee to come up. ;-). So I wrote the following script. (I am new to js programming and yes i know that my script sucks :-) )

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

Many problems occured. The resulting output did not show few links on it. Peacock, Crow, Swan, Raven are not seen in the output and all the
tags are messed up after it becomes static with spaces printed above and no breaks between the links. As a beginner javascript programmer i am stuck here and any assistance in the right direction would be much appreciated. Any way to elegantly solve this problem? Thanks.

paul bullard.

PS: I am using Fx 3.0.11.

Was it helpful?

Solution

Have you considered using innerHTML?

 var marq = document.getElementsByTagName('marquee')[0];
 var div = document.createElement('div');
 div.innerHTML = marq.innerHTML;
 marq.parentNode.appendChild(div);
 marq.parentNode.removeChild(marq);

Not the most efficient, but straight-forward.

See: http://jquery.nodnod.net/cases/586

OTHER TIPS

As for the reason that your resultant document ended up missing a few nodes, I can tell you why:

When you appendChild to another node, the DOM removes it from wherever it used to be. So when you go through the first node, it's removing children at the same time as it advances i down the DOM. Assume that A, B, C, etc. are child nodes, and this is what happens at the start of your 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

You can fix this in one of two ways. Firstly, you could make this change:

fixedElement.appendChild(marqueeElement.childNodes[i]);
// becomes
fixedElement.appendChild(marqueeElement.childNodes[i].cloneNode());

so you're always manipulating a cloned node, and the original <marquee> doesn't have elements removed, or you can make this change:

fixedElement.appendChild(marqueeElement.firstChild);

so that you always take the first item in the <marquee> and don't lose elements that way.

If your goal is to get rid of <marquee>s on all web sites, perhaps the best way to do so is to just edit your userContent.css file to include the following:

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.
   */
}

(I think that's actually already included in that file as a template, even :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top