jQuery: collapsible menu tree: a practical example of DOM traversing

jQuery: collapsible menu tree: a practical example of DOM traversing

Traversing the DOM is pretty easy with jQuery selectors and methods. A simple nested menu can be also traversed with a custom jQuery walker object which associates a particular action to every list items that, in turn, contains a sublist. The animation will simply hide or show the submenu.

We start with the following nested HTML structure:

<ul id="tree">
    <li>
        <a href="#">Item</a>
          <ul>
              <li>Item</li>
              <li>Item</li>
              <li>Item</li>
          </ul>
    </li>
    <li>
        <a href="#">Item</a>
        <ul>
              <li>
                  <a href="#">Item</a>
                  <ul>
              <li>Item</li>
              <li>Item</li>
              <li>Item</li>
          </ul>
              </li>
              <li>Item</li>
              <li>Item</li>
          </ul>
    </li>
</ul>

As you can see, the only elements we're interested in are the hyperlinks and the sublists. You can notice that some of these links are followed by a nested list in the DOM tree. So we can say that we're only interested in those links followed by an unordered list.

We can hide these sublists with a simple CSS declaration. Then we need to iterate over all links and trigger a click event only when a link has a list as its next sibling in the DOM tree:

var MenuTree = {
    collapse: function(element) {

        element.slideToggle(600);

    },

    walk: function() {

        $('a', '#tree').each(function() {

            var $a = $(this);
            var $li = $a.parent();

            if ($a.next().is('ul')) {

                var $ul = $a.next();

                $a.click(function(e) {

                    e.preventDefault();
                    MenuTree.collapse($ul);

                    $a.toggleClass('active');

                });

            }



        });


    }
};

MenuTree.walk();​

Our check is as the following:

if ($a.next().is('ul')) {


}

The is() method checks whether an element matches a given jQuery selector. In this case we make sure that the next sibling of a link is an unordered list. In that case, then, we associate an action to the targeted link.

You can see the above code in action on this page.