Minimalistic Navigation Plugin

by Rahul

HTML

<ul class="nav-menu horizontal">
    <li>
        <a href="#">Menu 1</a>
        <ul>
            <li><a href="#">Submenu 1</a></li>
            <li><a href="#">Submenu 2</a>
                <ul>
                    <li><a href="#">Subsubmenu 1</a></li>
                    <li><a href="#">Subsubmenu 2</a></li>
                    <li><a href="#">Subsubmenu 3</a></li>
                    <li><a href="#">Subsubmenu 4</a></li>
                </ul>
            </li>
            <li><a href="#">Submenu 3</a></li>
            <li><a href="#">Submenu 4</a>
                <ul>
                    <li><a href="#">Submenu 1</a></li>
                    <li><a href="#">Submenu 2</a>
                        <ul>
                            <li><a href="#">Submenu 1</a></li>
                            <li><a href="#">Submenu 2</a></li>
                            <li><a href="#">Submenu 3</a></li>
                            <li><a href="#">Submenu 4</a></li>
                        </ul>
                    </li>
                    <li><a href="#">Submenu 3</a></li>
                    <li><a href="#">Submenu 4</a></li>
                </ul>
            </li>
        </ul>
    </li>
    <li>
        <a href="#">Menu 2</a>
        <ul>
            <li><a href="#">Submenu 1</a></li>
            <li><a href="#">Submenu 2</a></li>
            <li><a href="#">Submenu 3</a>
                <ul>
                    <li><a href="#">Submenu 1</a></li>
                    <li><a href="#">Submenu 2</a>
                        <ul>
                            <li><a href="#">Submenu 1</a>
                                <ul>
                                    <li><a href="#">Submenu 1</a></li>
                                    <li><a href="#">Submenu 2</a></li>
                                    <li><a href="#">Submenu 3</a></li>
                                    <li><a href="#">Submenu 4</a></li>
                                </ul>
                            </li>
        ...

CSS

a,
a:link,
a:visited {
    display: block;
    text-decoration: none;
    color: black;
}

a:hover {
    color: blue;
}

ul.vertical > li > ul {
    margin-left: 10px;
    
}

ul.horizontal {
    display: block;
    border: 1px solid #333;
    height: 30px;
}

ul.horizontal > li {
    float: left;
    position: relative;
}

ul.horizontal li a {
    padding: 5px 10px;
}

ul.horizontal ul {
    box-shadow: 2px 2px 6px 0px #ccc;
}

ul.horizontal > li > ul {
    position: absolute;
    width: 130px;
    left: -1px;
    top: 30px;
    background-color: #fff;
    border: 1px solid #333;
}

ul.horizontal > li > ul li {
    position: relative;
}

ul.horizontal > li > ul ul {
    position: absolute;
    top: -1px;
    left: 130px;
    width: 130px;
    background-color: #fff;
    border: 1px solid #333;
}

JavaScript

(function($){
    
    function traverseItems($items, hover) {
        $items.each(function(){
            var $item = $(this),
                $submenu = $item.children("ul").hide();
            if ($submenu.length) {
                if (hover) {
                    $item.hover(function(){
                        clearTimeout($submenu.data('timeout'));
                        if ($submenu.is(':animated')) {
                            $submenu.show();
                        } else {
                            $submenu.stop(false, true).fadeIn();
                        }
                    },
                    function(){
                        $submenu.data('timeout', setTimeout(function(){$submenu.stop(true, true).fadeOut();}, 200));
                    }).children("a").append(" \>");
                } else {
                    $item.children("a").click(function(){
                        $submenu.stop(true, true).fadeToggle();
                        return false;
                    }).append(" \>");
                }
                traverseItems($submenu.children("li"), hover);
            }
        });
    }
    
    $.fn.navMenu = function (options){
        var defaults = {
            showToggle: false,
            openOnHover: false
        };
        options = $.extend({}, defaults, options);

        return this.each(function(){
            var $this = $(this)
                    .addClass("nav-menu"),
                $items = $this.children("li");
            
            traverseItems($items, options.openOnHover);

            if (options.showToggle) {
                $showAll = $("<a></a>")
                    .attr("href", "#")
                    .addClass("show-all")
                    .text("Toggle all")
                    .toggle(function(){
                        $this.find("ul").stop(true, true).show('fade');
                        return false;
                    }, function(){
                       ...