Pull to refresh

jQuery: Древовидное меню c памятью, возможность добавления подуровней

Reading time5 min
Views12K
Скрипт, — реакция на частые просьбы о подобной разработке на форуме javascript.ru. Появились мысли, что интерес проявится
и у Хаброжителей.

Плагин делался быстро, — заинтересовала идея реализации произвольнной вложенности табов без наращивания скриптов. Большую помощь оказал devote. Позже, по просьбе, были добавлены: cookie-память и установка классов к активным вкладкам.


Об HTML cоставляющей:

HТML код для вкладок первого уровня выглядит так:
<ul>
<li><a href="#">категория 1</a>V</li>
<li><a href="#">категория 2</a></li>

</ul>

Красным показана место вставки очередного подуровня меню (метка вставки только для первой ссылки, для остальных пунктов, — по аналогии; уровень вложенности может различаться по пунктам меню), — уровень вложенности регулируете сами, *имхо более трёх-4x уровней затрудняет юзабилити…

В последнем уровне каждой ветки, в тегах <a ...> проставляем в атрибутах href="#" реальные ссылки
(если это необходимо).

Плагин запускается установкой кода <script>$('#nav_menu_content').tree_menu()</script>, после последнего тега меню; где — #nav_menu_content, идентификатор меню.

Код HTML — странички вместе со скриптом, под спойлером, к версии библиотек jQuery, — вроде не чувствительно, проверялось от версии 1.4.1 до 1.9.1.
HTML + скрипт
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<script type="text/javascript" src="http://yandex.st/jquery/1.9.1/jquery.min.js"></script>

<style>
    #nav_menu_content * {
        margin: 0;
        padding:  0;
        margin: 0;
        padding:  0;
        -moz-user-select: none;
        -khtml-user-select: none;
        user-select: none;
    }
    #nav_menu_content{
        list-style: none;
        padding-left: 12px;
        display:inline:block;
        width:180px;
    }
    #nav_menu_content ul {
        list-style-position: outside;
        text-align:left;
        padding-left: 12px;
        list-style: none;
        display: none;
    }
    #nav_menu_content li {
        list-style: none;
        margin:4px auto 4px 4px;
        padding:2px 4px;
    }

    #nav_menu_content li {
        border:1px solid #C4C4C6;
        background-color: #E0EDED;
        font-size:120%;
        text-shadow:1px 1px 1px #83A0A0;
    }
    #nav_menu_content li ul li{
        border:1px solid blue;
        text-shadow:none;
        font-size:80%;
        background-color: #C1C1E5;
    }
    #nav_menu_content li ul li ul li{
        font-size:90%;
        border:1px solid green;
        background-color: #BCDEBC;
    }
   #nav_menu_content > li > a:before {
       background: url(http://hostjs-mybb2011.narod.ru/img/icon.png) 0 0 no-repeat transparent;
       content: " ";
       display: block;
       float: left;
       height: 16px;
       margin-left: 2px;
       margin-top: 2px;
       width: 16px;
    }
   #nav_menu_content > li > a.active:before {
       background-position:0 -16px;
    }

   #nav_menu_content a {
       padding: 1px 4px!important;
       -moz-user-select: none;
       -khtml-user-select: none;
       user-select: none;      
    }

   #nav_menu_content > li > ul > li > a.active {
        -moz-box-shadow: 0 0 3px #620D62; /* Для Firefox */
        -webkit-box-shadow: 0 0 3px #620D62;
         box-shadow: 0 0 3px #620D62; /* Параметры тени */
         font-weight:700;
    }

    /*Cтиль Ссылки на текущую страницу*/
   #nav_menu_content li ul li.a-active {

        background-color:#D6D6FA!important;
        border:1px dotted #9D9DBA!important;
        -moz-box-shadow: 0 0 3px rgba(0,0,0,0.5); /* Для Firefox */
        -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.5);
        box-shadow: 0 0 3px rgba(0,0,0,0.5); /* Параметры тени */
    }
   li.a-active a{
        color:#0000CC!important;
        font-weight:700;
    }
    #nav_menu_content li ul li ul li ul li{
        border:1px solid green;

        background-color: #C1C1E5;
        color:#fff!important;
    }
    #nav_menu_content li ul li ul li ul li a{
       padding: 1px 0 1px 4px!important;
        color:#000;
    }
</style>

<script type="text/javascript">
function setcookie(a,b,c) {if(c){var d = new Date();d.setTime(d.getTime()+c);}if(a && b) document.cookie = a+'='+b+';path=/'+(c ? '; expires='+d.toUTCString() : '');else return false;}
 function getcookie(a) {var b = new RegExp(a+'=([^;]){1,}');var c = b.exec(document.cookie);if(c) c = c[0].split('=');else return false;return c[1] ? c[1] : false;}
</script>

<script type="text/javascript">

$.fn.tree_menu = function() {


        var nav = this;
        var uls = nav.find("ul");


	var coci_MENU= getcookie( "MENU" );
	if (coci_MENU) {
	setcookie( "MENU",coci_MENU ,30*3600*24*1000 );

	// тут получаем индексы из куки и перебираем их:
        var showedElems = ( coci_MENU || "" ).split(",");
        for( var i = 0; i < showedElems.length; i++ ) {
            // отображаем при загрузке то что надо.
            $( uls[ showedElems[ i ] ] ).prev('a').addClass('active')  //Добавляем класс к Активным эл-там меню;
            $( uls[ showedElems[ i ] ] ).show();
        }}


        //Добавляем класс к ссылке на текущую страницу, если она есть;
        var Url = document.URL.split('#')[0];
        $('> li ul',nav).find('a:not([href^="#"])').each(function() {
            var S = $(this).attr('href').split('#')[0];
            if(S&&Url.indexOf(S)!=-1) $(this).parent().addClass('a-active');
        });

        nav.find("a").click(function() {
            var Lnk=$(this).attr("href");
            if(Lnk==''||Lnk.indexOf('#')==0) setcookie( "MENU",1 ,-1);
            var self = $(this).next();
            if ( self.length == 0 ) return;


            var showedElems = [];
            uls.each(function( index ){

                    if ( this === self[0] ) {
                        if ( self.css('display') == "none" ) {
                           showedElems.push(index);$(this).prev('a').addClass('active');
                        }  else $(this).prev('a').removeClass('active');
                        $( this ).slideToggle(400);return true;
                    } 
                    if ( jQuery.inArray( this, self.parents( "ul" ) ) == -1 ) {
                        $(this).prev('a').removeClass('active');$(this).slideUp(400);return true;
                    }
                    showedElems.push(index);
           });

                // эту переменную  суём в куки,
                setcookie( "MENU", showedElems.join(",") ,30*3600*24*1000 );

                return false;

        });
}
</script>
</head>
<body style="padding-left:23%;padding-top:60px;">

<ul id='nav_menu_content'>
    <li><a href='#0'>Категория 1</a>
        <ul>
            <li><a href="#">Субкатегория 1</a>
                <ul>
                    <li><a href="view_cat.php?...">Подкатегория 1</a></li>
                    <li><a href="view_cat.php?...">Подкатегория 2</a></li> 
                </ul>
            </li>
           <li><a href="#">Субкатегория 2</a>
                <ul>
                    <li><a href="view_cat.php?...">Подкатегория 3</a></li>
                    <li><a href="view_cat.php?...">Подкатегория 4</a></li>
                </ul>
            </li>
           <li><a href="#">Субкатегория 3</a>
                <ul>
                    <li><a href="#">Подкатегория 5</a>
                        <ul>
                            <li><a href="view_cat.php?...">№1.  категория 1</a></li>
                            <li><a href="view_cat.php?...">№3.  категория 2</a></li>
                       </ul>
                    </li>
                    <li><a href="view_cat.php?...">Подкатегория 6</a></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><a href='#0'>Категория 2</a>
        <ul>
           <li><a href="#">Субкатегория 4</a>
                <ul>
                    <li><a href="view_cat.php?...">Подкатегория 7</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>   <script>$('#nav_menu_content').tree_menu();</script> <!-- Запуск -->


</body>
</html>


ссылка на демо
Tags:
Hubs:
-8
Comments17

Articles