469,311 Members | 2,444 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,311 developers. It's quick & easy.

Question about cloneNode behavior

I have a button on a page whose onclick funtion is posted below. I am
basically trying to get all the spans in the page and list them in 2
columns. I get the list of spans using getElementsByTagName('span').

I dont want to move the spans themselves into my 2 column list(i.e I
want them to stay where they are on the page), so I figured I needed
to clone each span. Each time I make a clone, the clone somehow gets
added to my original list of spans, so I end up in an infinite loop
adding the first few elements again and again. How is this supposed to
be done? Javascript n00b here...any advise is greatly
appreciated...

function getSpans()
{
var allspans=document.getElementsByTagName("span");
var infoDiv = null;
var tmp;
for(var element, i=0;element=allspans[i];i++)
{
tmp=element.cloneNode(true);
alert(i +' '+tmp.innerHTML +' ' +allspans.length); <<<<<
allspans keeps increasing
if( i%2 == 0 ){
if( i!=0 ) list1.appendChild(infoDiv);
infoDiv=document.createElement('div');
}
infoDiv.appendChild(tmp);
}
}

list1 is a div id

Thanks
Jun 27 '08 #1
3 1334
On Apr 16, 2:32 pm, santosh....@gmail.com wrote:
I have a button on a page whose onclick funtion is posted below. I am
basically trying to get all the spans in the page and list them in 2
columns. I get the list of spans using getElementsByTagName('span').

I dont want to move the spans themselves into my 2 column list(i.e I
want them to stay where they are on the page), so I figured I needed
to clone each span. Each time I make a clone, the clone somehow gets
added to my original list of spans, so I end up in an infinite loop
adding the first few elements again and again.
The collection returned by getElementsByTagName is live, that is, as
you add more spans to the document, more are added to your collection.

How is this supposed to
be done?
Convert the collection to an array, something like:

function toArray(obj) {

if (typeof obj.length != 'number') { return [obj]; }

var result = [];
for (var i=0, len=obj.length; i<len; i++) {
result.push(obj[i]);
}
return result;
}

You can also work backward through the collection using its initial
length if you are adding the spans lower in the DOM than the last in
the initial collection, but that doesn't seem to be a good idea here
(and can cause maintenance issues anyway).

Javascript n00b here...any advise is greatly
appreciated...

function getSpans()
{
var allspans=document.getElementsByTagName("span");
var infoDiv = null;
var tmp;
for(var element, i=0;element=allspans[i];i++)
Why not the more common:

var element;
for (var i=0, len=allspans.length; i<len; i++) {
element = allspans[i];
{
tmp=element.cloneNode(true);
alert(i +' '+tmp.innerHTML +' ' +allspans.length); <<<<<
allspans keeps increasing
if( i%2 == 0 ){
You could just use i%2
if( i!=0 ) list1.appendChild(infoDiv);
Don't expect element IDs to be global variables, that is an IE
invention. Use getElementById.

infoDiv=document.createElement('div');
}
infoDiv.appendChild(tmp);
}

}

list1 is a div id
function getSpans(id) {

var target = document.getElementById(id);
var allspans = toArray(document.getElementsByTagName('span'));
var div = document.createElement('div');

for (var i=0, len=allspans.length; i<len; i++) {
div.appendChild(allspans[i].cloneNode(true));
}

target.appendChild(div);
}

Needs a bit of feature detection and testing, but shows the concept I
hope.
--
Rob

Jun 27 '08 #2
Thanks a lot!

The toArray() was what I needed. Didn't know about live collections
and lost a bit of hair trying to figure out what it was doing.

About the 'for' loop style, it's part of some existing code and I
hadn't actually given it any thought until you pointed out the
conventional form. It works fine though. The i%2==0 is required as I
am trying to create a div every 2 spans.

Thanks once again for all the pointers...much appreciated.
Jun 27 '08 #3
RobG wrote:
function toArray(obj) {

if (typeof obj.length != 'number') { return [obj]; }

var result = [];
for (var i=0, len=obj.length; i<len; i++) {
result.push(obj[i]);
}
return result;
}
Given that Array.prototype.push() requires JScript 5.5, much more efficient
and equally compatible is

function toArray(obj)
{
return [].slice.call(obj);
}

See http://PointedEars.de/es-matrix
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Richard Trahan | last post: by
1 post views Thread by Petr Felzmann | last post: by
reply views Thread by Sullivan WxPyQtKinter | last post: by
2 posts views Thread by Csaba Gabor | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
1 post views Thread by Geralt96 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.