Question about cloneNode behavior

Discussion in 'Javascript' started by santosh.pjb@gmail.com, Apr 16, 2008.

  1. Guest

    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++)
    {
    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
     
    , Apr 16, 2008
    #1
    1. Advertising

  2. RobG Guest

    On Apr 16, 2:32 pm, 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);
    }
    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++)


    Why not the more common:

    var element;
    for (var i=0, len=allspans.length; i<len; i++) {
    element = allspans;

    > {
    > 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.cloneNode(true));
    }

    target.appendChild(div);
    }

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


    --
    Rob
     
    RobG, Apr 16, 2008
    #2
    1. Advertising

  3. Guest

    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.
     
    , Apr 16, 2008
    #3
  4. 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);
    > }
    > 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
     
    Thomas 'PointedEars' Lahn, Apr 17, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?TW9ua2V5Qm95?=
    Replies:
    2
    Views:
    447
    =?Utf-8?B?TW9ua2V5Qm95?=
    Jun 6, 2004
  2. Sullivan WxPyQtKinter
    Replies:
    0
    Views:
    1,963
    Sullivan WxPyQtKinter
    Mar 14, 2006
  3. Chameleon

    appendChild & cloneNode

    Chameleon, Jun 1, 2009, in forum: XML
    Replies:
    25
    Views:
    3,785
    Thomas 'PointedEars' Lahn
    Jun 3, 2009
  4. itsme

    XmlDocument and cloneNode

    itsme, Oct 14, 2003, in forum: ASP .Net Building Controls
    Replies:
    0
    Views:
    152
    itsme
    Oct 14, 2003
  5. Janis Papanagnou
    Replies:
    1
    Views:
    125
Loading...

Share This Page