Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: to loop or not to loop?

  1. #1
    Join Date
    Sep 2008
    Posts
    119
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Question to loop or not to loop?

    Let's say I have the following HTML -


    <form id="form1" name="form1">
    <ul id="mn" name="mn">
    <li id="one" name="one">bleh</li>
    <li id="blarg" name="blarg">bluh</li>
    <li id="goats" name="goats">blah</li>
    </ul>
    </form>


    Normally, there would be a loop function to gather all of the elements within the "mn" ul element. I am curious if there is an alternative to looping that will provide me with an array of the li elements.
    document.write is document.wrong

  2. #2
    Join Date
    Dec 2008
    Location
    Portsmouth, UK
    Posts
    1,891
    Thanks
    2
    Thanked 441 Times in 435 Posts

    Default

    var lis=document.getElementById(mn).getElementsByTagName('LI');

    is a 'collection' which is similar to an array.

  3. The Following User Says Thank You to vwphillips For This Useful Post:

    Falkon303 (07-09-2009)

  4. #3
    Join Date
    Sep 2008
    Posts
    119
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Thumbs up

    Thanx much for the response. So in theory, this would be more efficient than looping through elements? I considered not using the "onload", but rather putting that in the javascript, but this is a much more useful way to retrieve elements in my opinion. Thanx for the help VW.

    Perhaps I'll do a time test on this in comparison to another method to see exactly what's going on.

    I'd love to hear more thoughts on this.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Element 	Collection</title>
    <script type="text/javascript">
    function retel()
    {
    count = document.getElementById('mn').getElementsByTagName('LI').length;
    for (i=0;i<=count-1;i++)
    {
    alert((i + 1) + ' of ' + count + ' Elements Found -> id:' + document.getElementById('mn').getElementsByTagName('LI')[i].id + '  -> Text:' + document.getElementById('mn').getElementsByTagName('LI')[i].firstChild.nodeValue);
    }
    }
    </script>
    </head>
    <body onload="retel();">
    <form id="form1" name="form1">
    <ul id="mn" name="mn">
    <li id="newid1" name="newid1">new1</li>
    <li id="newid2" name="newid2">new2</li>
    <li id="newid3" name="newid3">new3</li>
    <li id="newid4" name="newid4">new4</li>
    <li id="newid5" name="newid5">new5</li>
    <li id="newid6" name="newid6">new6</li>
    <li id="newid7" name="newid7">new7</li>
    <li id="newid8" name="newid8">new8</li>
    </ul>
    </form>
    </body>
    </html>
    document.write is document.wrong

  5. #4
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    I wouldn't worry about efficiency for a function that (more than likely) runs in linear or constant time. That aside, the built-in browser version should be faster.

    To convert into an array, you could do:
    Code:
    var lis = Array.prototype.slice.call (document.getElementById (mn).getElementsByTagName ('li'));
    I may be mistaken, but the above code might give IE issues. In that case, if you need it as an array, you could always use something like this:
    Code:
    function toArray (xs) {
      var ys = [];
      for (var i = 0; i < xs.length; ++i) {
        ys [i] = xs [i];
      }
      return ys;
    }
    Trinithis

  6. #5
    Join Date
    Jul 2006
    Posts
    497
    Thanks
    8
    Thanked 70 Times in 70 Posts

    Default

    If you know that you want all children, you could even skip the looping and just get ul.childNodes.
    -- Chris
    informal JavaScript student of Douglas Crockford
    I like wikis - a lot.

  7. #6
    Join Date
    Sep 2008
    Posts
    119
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Smile

    Quote Originally Posted by Jesdisciple View Post
    If you know that you want all children, you could even skip the looping and just get ul.childNodes.
    Thanks for this. I am very interested. Could you please explain a bit more in depth or possibly give an example?

    Thanx much,

    - Ben
    document.write is document.wrong

  8. #7
    Join Date
    Jul 2006
    Posts
    497
    Thanks
    8
    Thanked 70 Times in 70 Posts

    Default

    The DOM (Document Object Model) keeps track of all children of every node in an array-like object called childNodes. Just access this property on any node to get that node's children.
    Quote Originally Posted by http://www.w3.org/TR/ElementTraversal/
    The DOM Level 1 Node interface also defines the childNodes attribute, which is a live list of all child nodes of the node; the childNodes list has a length attribute to expose the total number of child nodes of all nodeTypes, useful for preprocessing operations and calculations before, or instead of, looping through the child nodes.
    EDIT: Note that grandchildren are not included in this list.
    -- Chris
    informal JavaScript student of Douglas Crockford
    I like wikis - a lot.

  9. #8
    Join Date
    Sep 2008
    Posts
    119
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Thumbs up

    Thanx much for the response.

    What I trying to accomplish is a DOM returned array string of node ids without having to use a looping function as posted earlier.

    I'll try and explain it here ---

    Now, running the script below, you'll see it returns the array length, and the id property of node #2, yet I can't help but wonder if there is such a usage as -

    document.getElementById('ul').childNodes.toArray().join("");

    Anything similar?

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>nodes</title>
    <script type="text/javascript">
    function get()
    {alert('How many LI Elements? : ' + document.getElementById('ul').childNodes.length);
    alert('LI Elements #2 id? : ' + document.getElementById('ul').childNodes[1].id);}
    </script>
    </head>
    <body onload="get();">
    <ul id="ul" name="ul">
    <li id="1" name="1">one</li>
    <li id="2" name="2">two</li>
    <li id="3" name="3">three</li>
    <li id="4" name="4">four</li>
    </ul>
    </body>
    </html>
    document.write is document.wrong

  10. #9
    Join Date
    Jul 2006
    Posts
    497
    Thanks
    8
    Thanked 70 Times in 70 Posts

    Default

    Oh, you want the IDs? No, there's no way to skip the loop for that. I thought you just wanted the elements.

    I am curious though why you're afraid of loops.
    -- Chris
    informal JavaScript student of Douglas Crockford
    I like wikis - a lot.

  11. #10
    Join Date
    Sep 2008
    Posts
    119
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Smile

    Quote Originally Posted by Jesdisciple View Post
    Oh, you want the IDs? No, there's no way to skip the loop for that. I thought you just wanted the elements.

    I am curious though why you're afraid of loops.
    I am not afraid of loops, but rather curious of some of the more obscured javascript functionality, such as using "nodeList.nextSibling" (as seen at - http://www.irt.org/xref/ie_5.htm ), or something similar to somehow increment through the elements.

    I am unsure how to use "nextSibling", but in some of the examples, it proceeds to the next element. Perhaps using "nextSibling.id" or something similar would work. Of course then we have to use a loop depending on the nodelength, so maybe there must always be a loop....

    Just curious if it can be done.

    hrm.
    document.write is document.wrong

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •