title: Traversing an html nested list using javascript
body: <p>I have an HTML list (<code>&lt;ul&gt;</code>, <code>&lt;li&gt;</code>, etc.) of pages, with multiple items at various depths. I am trying to write some code to traverse this list one element at a time. So a "next " button would return the ID of the following <code>&lt;li&gt;</code> element, which could be a direct sibling of the current element, or it would be in a child <code>&lt;ul&gt;</code> element, or it could be in a parent <code>&lt;ul&gt;</code> element. Likewise, a "prev" button would do the same, but in reverse.</p>
  
  <p>Here is some example html:</p>
  
  <pre><code>&lt;ul&gt;
    &lt;li id="post_item_1"&gt;&lt;a href="#post1"&gt;Vestibulum ultrices, ante non tincidunt molestie, purus enim varius urna, nec bibendum...&lt;/a&gt;
  
     &lt;ul&gt;
     &lt;li id="post_item_26"&gt;&lt;a href="#post26"&gt;This planet has &amp;mdash; or rather had &amp;mdash; a problem, which was this: most of...&lt;/a&gt;
  
      &lt;ul&gt;
      &lt;li id="post_item_27"&gt;&lt;a href="#post27"&gt;A towel, it says, is about the most massively useful thing an interstellar hitch...&lt;/a&gt;
      &lt;/li&gt;
     &lt;/ul&gt;
  
     &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li id="post_item_2"&gt;&lt;a href="#post2"&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nec velit augue,...&lt;/a&gt;
  
     &lt;ul&gt;
     &lt;li id="post_item_58"&gt;&lt;a href="#post58"&gt;Reply to first post, with an edit&lt;/a&gt;
     &lt;/li&gt;
  
     &lt;li id="post_item_59"&gt;&lt;a href="#post59"&gt;Another reply to first post, made after the first reply&lt;/a&gt;
     &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li id="post_item_4"&gt;&lt;a href="#post4"&gt;Phasellus vitae est tellus, vel aliquam lectus. Cras augue tellus, pulvinar a blandit...&lt;/a&gt;
  
     &lt;ul&gt;
     &lt;li id="post_item_60"&gt;&lt;a href="#post60"&gt;Reply to second post&lt;/a&gt;
  
     &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li id="post_item_3"&gt;&lt;a href="#post3"&gt;Pellentesque consequat urna mauris, luctus adipiscing enim. Sed quis lectus vel...&lt;/a&gt;
    &lt;/li&gt;
    &lt;li id="post_item_28"&gt;&lt;a href="#post28"&gt;"The Babel fish" said The Hitchhiker's Guide to the Galaxy quietly, "is small, yellow...&lt;/a&gt;
  
    &lt;/li&gt;
    &lt;li id="post_item_61"&gt;&lt;a href="#post61"&gt;Hello there, it is very worrying&lt;/a&gt;
  
     &lt;ul&gt;
     &lt;li id="post_item_62"&gt;&lt;a href="#post62"&gt;Don't be scared, or scarred, or sacred, or Skesis!&lt;/a&gt;
     &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
  
    &lt;li id="post_item_67"&gt;&lt;a href="#post67"&gt;Well, to be fair, at the end of the day, when all is said and done, I'd like to...&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  </code></pre>
  
  <p>I've played around with jquery for some hours, and this is as far as I have got:</p>
  
  <pre><code>if (!node) {
  // start with the selected node
  node = $('#content #postNavigator ul li.selected')
  }   
  
  
  if ( $(node).has('ul').length ) {
      // has child &lt;ul&gt; 
  nextNode = $($(node).children()[1]).children()[0];      
  } 
  else {
  // has a sibling
  if ($(node).next('li').length) {
      nextNode = $(node).next('li');
  }
  else {  
  
      // recursion needed here - this code will return parent, but only when 1 level deep.
      if ($(node).parent().parent().next('li').length) {
          nextNode = $(node).parent().parent().next('li');
      }
      else {          
          return false;
          }
      }               
  }
  </code></pre>
  
  <p>The above will return the next node, or a child node if there is one, and will return the parent node if there are no more siblings or children, but only one level deep. The HTML list can be of an unlimited depth, so some kind of recursion may be needed? This is as far my skills can take me. I haven't even begun to think about the "prev" link, to work on this list in the same way but in reverse order.</p>
  
  <p>I asked the same on devshed (a few weeks ago) but have had no replies.</p>
  
  <hr>
  
  <p>Thank you all for your answers.</p>
  
  <p>Ninja, I have implemented yours with some success. I can now navigate up and down my nested list very nicely.</p>
  
  <p>A further question, if you would be so kind: I need the ability to start the "position" at a point within the tree. Users can select a node within the tree by way of a hash (e.g. #post9) - they can click a node anywhere in the list to select it, or they can bookmark the url, which would  include that node's own hash.</p>
  
  <p>So my further question is: how would I locate a node within the tree and get it's position, using the hash in the URL? The hash in the URL correlates with the id of the li node
  .</p>