Question about cloneNode behavior

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • santosh.pjb@gmail.com

    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 getElementsByTa gName('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=docume nt.getElementsB yTagName("span" );
    var infoDiv = null;
    var tmp;
    for(var element, i=0;element=all spans[i];i++)
    {
    tmp=element.clo neNode(true);
    alert(i +' '+tmp.innerHTML +' ' +allspans.lengt h); <<<<<
    allspans keeps increasing
    if( i%2 == 0 ){
    if( i!=0 ) list1.appendChi ld(infoDiv);
    infoDiv=documen t.createElement ('div');
    }
    infoDiv.appendC hild(tmp);
    }
    }

    list1 is a div id

    Thanks
  • RobG

    #2
    Re: Question about cloneNode behavior

    On Apr 16, 2:32 pm, santosh....@gma il.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 getElementsByTa gName('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 getElementsByTa gName 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=docume nt.getElementsB yTagName("span" );
    var infoDiv = null;
    var tmp;
    for(var element, i=0;element=all spans[i];i++)
    Why not the more common:

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

    infoDiv=documen t.createElement ('div');
    }
    infoDiv.appendC hild(tmp);
    }
    >
    }
    >
    list1 is a div id
    function getSpans(id) {

    var target = document.getEle mentById(id);
    var allspans = toArray(documen t.getElementsBy TagName('span') );
    var div = document.create Element('div');

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

    target.appendCh ild(div);
    }

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


    --
    Rob



    Comment

    • santosh.pjb@gmail.com

      #3
      Re: Question about cloneNode behavior

      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.

      Comment

      • Thomas 'PointedEars' Lahn

        #4
        Re: Question about cloneNode behavior

        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

        Comment

        Working...