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.

Back to top