views:

309

answers:

4

Hi everybody, 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.

A: 
<marquee> is not a standard HTML tag. It's only available in IE and partly in Firefox.
jao
How exactly does that help with his question?
thedz
Yeah, this is a worthless answer.
Josh Stodola
But he is right *gg*
Hippo
and marquee is ugly :-)
jao
+1  A: 

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

thedz
Dude you are a genius. I wonder how i didn't think of that. :-?Thanks a ton.
A: 

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

Paul Fisher
+2  A: 

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.

Paul Fisher