jQuery для начинающих. Часть 2. JavaScript Меню.



    В первой части были рассмотрены базовые принципы работы селекторов и приведены несколько примеров, в данной статье я постараюсь акцентировать внимание на реализации JavaScript меню для Вашего сайта.

    Если Вам готовый код наглядней документации, то переходим от слов к делу, т.е. на страницу с примерами.


    Slide меню


    Два slide-меню на странице: вверху и внизу.



    Кликаем по ссылке с классом «btn-slide», выезжает панель с меню.

    Частично данный пример присутствует в первой части, так что особо углубляться в реализацию не буду, приведу лишь JavaScript код с пояснениями:

    <script type="text/javascript">
    // когда страница загрузится
    $(document).ready(function(){
    	// вешаем обработчик на ссылку с классом "btn-slide" (верхнее меню)
    	$(".btn-slide").click(function(){
    		// выдвигаем/прячем панель с id = panel1
    		$("#panel1").slideToggle("slow");
    		// изменяем класс самой ссылки
    		$(this).toggleClass("active");
    		// и ничего не делаем дальше (дабы не было перехода по ссылки)
    		return false;
    	});
    	
    	// вешаем обработчик на ссылку с классом "btn-slide2" (нижнее меню)
    	$(".btn-slide2").click(function(){
    		// выдвигаем/прячем панель с id = panel2
    		$("#panel2").slideToggle("slow");
    		// изменяем класс самой ссылки
    		$(this).toggleClass("active2");
    		// и ничего не делаем дальше (дабы не было перехода по ссылки)
    		return false;
    	});
    });
    </script>


    Slide меню 2


    Slide-меню слева и справа страницы. Для начала приготовим HTML:

    <div class="left">
        <!-- Непосредственно содержание меню, мы его прячем -->
        <div class="panel">
        	<ul>
        	   <li><a href="#" title="Элемент 1">Элемент 1</a></li>
        	   <li><a href="#" title="Элемент 2">Элемент 2</a></li>
        	   <li><a href="#" title="Элемент 3">Элемент 3</a></li>
        	</ul>
        	<ul>
        	   <li><a href="#" title="Элемент 1">Элемент 1</a></li>
        	   <li><a href="#" title="Элемент 2">Элемент 2</a></li>
        	   <li><a href="#" title="Элемент 3">Элемент 3</a></li>
        	</ul>
        	<ul>
        	   <li><a href="#" title="Элемент 1">Элемент 1</a></li>
        	   <li><a href="#" title="Элемент 2">Элемент 2</a></li>
        	   <li><a href="#" title="Элемент 3">Элемент 3</a></li>
        	</ul>
        </div> 
        <!-- Панелька с кнопкой -->
        <p class="slide"><a href="#" class="btn-slide">Меню</a></p>
    </div>
    


    У нас должно получиться что-то наподобие следующего:



    Теперь создадим обработчик событий для ссылок с классом «btn-slide»:

    	// создаем обработчик событий для ссылок с классом "btn-slide"
    	$(".btn-slide").toggle(function(){
    		// ... 1-ый клик по ссылке
    		// возвращаем false
    		return false;
    	},function(){
    		// ... 2-ой клик по ссылке
    		// возвращаем false
    		return false;
    	});
    

    Затем нам необходимо найти элемент с классом «panel» и выдвинуть его на 120 пикселей:
    // идем по DOM'у на 2-а уровня вверх, внутри элемента (это div c классом left/right) находим нужный нам элемент и приращиваем ему 120 пикселей в ширину
    $(this).parent().parent().find(".panel").animate({"width": "+=120px"}, "slow");
    // заменяем класс кнопки (для изменение стрелочки)
    $(this).toggleClass("active"); 
    


    Соединяем это вместе:
    $(document).ready(function(){
    	$(".btn-slide").toggle(function(){
    		$(this).parent().parent().find(".panel").animate({"width": "+=120px"}, "slow");
    		$(this).toggleClass("active"); return false;
    	},function(){
    		$(this).parent().parent().find(".panel").animate({"width": "-=120px",opacity: "hide"}, "slow");
    		$(this).toggleClass("active"); return false;
    	});	 
    });
    


    Drop-down меню


    Одна из самых распространенных реализаций меню для сайта это горизонтальное выпадающее меню, его конечно можно реализовать при помощи CSS, но статья у нас о jQuery, так что будем орудовать оным. Начнем с HTML'a (замечу, что для всех остальных примеров код практически не отличается):



    Ну и собственно сам HTML:

        <div class="topmenu">
            <ul>
                <li><a href="#" title="Меню 1">Меню 1</a>
                    <ul>
                	   <li><a href="#" title="Элемент 1.1">Элемент 1.1</a></li>
                	   <li><a href="#" title="Элемент 1.2">Элемент 1.2</a></li>
                	   <li><a href="#" title="Элемент 1.3">Элемент 1.3</a></li>
                    </ul>
                </li>
                <li><a href="#" title="Меню 2">Меню 2</a>
                    <ul>
                	   <li><a href="#" title="Элемент 2.1">Элемент 2.1</a></li>
                	   <li><a href="#" title="Элемент 2.2">Элемент 2.2</a></li>
                	   <li><a href="#" title="Элемент 2.3">Элемент 2.3</a></li>
                    </ul>
                </li>
                <li><a href="#" title="Меню 3">Меню 3</a>
                    <ul>
                	   <li><a href="#" title="Элемент 3.1">Элемент 3.1</a></li>
                	   <li><a href="#" title="Элемент 3.2">Элемент 3.2</a></li>
                	   <li><a href="#" title="Элемент 3.3">Элемент 3.3</a></li>
                    </ul>
                </li>
            </ul>       
        </div>
    


    Далее нам необходимо добавить обработчик для события hover для элементов li:
        $('.topmenu ul li').hover(
            function() {
                // ...
            },
            function() {
                // ...
            }
        );
    


    И отображаем под-меню:
    // находим элемент ul и вызываем анимацию slideDown
    $(this).find('ul').slideDown();
    // изменяем фон выбранного элемента путем добавления класса active
    $(this).addClass("active");
    


    А теперь всё вместе:
    $(document).ready(function(){
        $('.topmenu ul li').hover(
            function() {
                $(this).addClass("active");
                $(this).find('ul').slideDown();
            },
            function() {
                $(this).removeClass("active");        
                $(this).find('ul').slideUp('fast');
            }
        );
    });
    


    Drop-down AJAX меню


    Горизонтальное выпадающее меню с подгрузкой элементов AJAX'ом.
    Для начала нам понадобится само меню:
        <div class="topmenu">
            <ul>
                <li id="menu1"><a href="#" title="Меню 1">Меню 1</a></li>
                <li id="menu2"><a href="#" title="Меню 2">Меню 2</a></li>
                <li id="menu3"><a href="#" title="Меню 3">Меню 3</a></li>
            </ul>
        </div>
    


    И заготовки для подменю, назовем их menu1.html, menu2.html и menu3.html — по id соответствующих элементов меню (скорей всего данные элементы будут генерироваться динамически, но для упрощения примера используем статические странички):



    Пример menu1.html:

    <ul>
        <li><a href="#" title="Элемент 1">Элемент 1</a></li>
        <li><a href="#" title="Элемент 2">Элемент 2</a></li>
        <li><a href="#" title="Элемент 3">Элемент 3</a></li>
    </ul>


    Теперь, как и в предыдущем примере, нам необходим обработчик события hover:

    $(document).ready(function(){
        $('.topmenu ul li').hover(
            function() {
                // ... тут необходимо внести изменения в код 
                $(this).addClass("active");
            },
            function() {
                // тут оставляем так как есть
                $(this).removeClass("active");        
                $(this).find('ul').slideUp('fast');
            }
        );
    });
    

    Теперь необходимо загрузить недостающие элементы меню посредством AJAX'a:
    // получаем id активного элемента меню
    var id = $(this).attr('id');
    // запихиваем активный элемент в локальную переменную
    var li = $(this);
    $.ajax({
         // формируем имя запрашиваемой посредством AJAX страницы
         url: 'ajax/'+id+'.html',
         beforeSend: function(){
              // перед тем как "спросить" изменяем класс элемента - отображаем loading картинку
              li.addClass('loading');
         },
         success: function(data){
              // наполняем подменю
              li.append(data);
              // показываем что получилось
              li.find('ul').slideDown();
              // убираем loading картинку
              li.removeClass('loading');
         }
    });
    

    Собираем:
    $(document).ready(function(){
        $('.topmenu ul li').hover(
            function() {
                // добавляем проверочку - не загружали ли до этого элементы
                if ($(this).find('ul').length == 0) {
                    var id = $(this).attr('id');
                    var li = $(this);
                    $.ajax({
                        url: 'ajax/'+id+'.html',
                        beforeSend: function(){
                             li.addClass('loading');
                        },
                        success: function(data){
                             li.append(data);
                             li.find('ul').slideDown();
                             li.removeClass('loading');
                        }
                    });
                } else {
                    $(this).find('ul').slideDown();
                }            
                $(this).addClass("active");
            },
            function() {            
                $(this).find('ul').slideUp('fast');            
                $(this).removeClass("active");
            }
        );
    });
    


    Drop-down меню


    Вертикальное выпадающее меню. Достаточно простенький примерчик:



    $(document).ready(function(){
        // добавить обработчик события hover
        $('.topmenu ul li').hover(
            function() {
                $(this).find('ul:first').slideDown();
            },
            function() {            
                $(this).find('ul:first').slideUp('fast'); 
            }
        );
        // всем элементам меню с вложенностью добавить символ »
        $('.topmenu li:has(ul)').find('a:first').append('»');
    });
    


    Float меню


    Плавающее меню. Нам понадобится плагин Dimensions (дабы работали методы height() и width()). Ну с HTML я думаю, Вы разберетесь:



    Теперь по порядку — начнем с получение информации о текущем расположении «плавающих» меню:

    // получаем информацию из css о расположении верхнего меню
    menu1 = parseInt($(".right").css("top").substring(0,$(".right").css("top").indexOf("px")));
    // расположении нижнего меню вычисляем отталкиваясь от размеров окна (96 взято на глаз)
    menu2 = $(window).height() - 96;
    


    Далее, нам необходимо «повесить» свою функцию для события scroll:
    $(window).scroll(function () { 
    // тут будем перетаскивать наши меню
    });
    


    Ну и собственно наполнение:
    $(window).scroll(function () { 
    	// определяем новое положение для наших меню
    	offset1 = menu1 + $(document).scrollTop() + "px";
    	offset2 = menu2 - $('.left .panel').height() + $(document).scrollTop() + "px";
    
    	// перетаскиваем элементы на новое место			
    	$('.right').animate({top:offset1},{duration:500,queue:false});
    	$('.left').animate({top:offset2},{duration:1000,queue:false});
    });
    


    Так же добавим отображение/скрытие элементов подменю:
        // для всех элементов "a" которые находятся в "li" со вложенными списками "ul"
        $('.panel ul li:has(ul) a').click(function() {
            // идем к паренту, находим "ul" и прячем/скрываем его
            $(this).parent().find('ul').slideToggle();  
            return false;      
        });
        // кнопка "+" - скрываем все "ul" вложенные в "li"
        $('a.plus').click(function(){
           // идем к паренту, находим следующий элемент в доме, ищем в нем "ul li ul", выполняем "slideUp"
           $(this).parent().next().find('ul li ul').slideUp('fast');
           return false; 
        });
        // кнопка "-" - отображаем все "ul" вложенные в "li"    
        $('a.minus').click(function(){
           // идем к паренту, находим следующий элемент в доме, ищем в нем "ul li ul", выполняем "slideDown"
           $(this).parent().next().find('ul li ul').slideDown('slow');
           return false; 
        });
    


    Так же Вы можете скачать все примеры в одном архиве.

    Цикл статей


    1. jQuery для начинающих
    2. jQuery для начинающих. Часть 2. JavaScript Меню.
    Метки:
    Поделиться публикацией
    Похожие публикации
    Комментарии 26
    • +7
      Вот так бы все статьи составлялись! 5 баллов!
      • +1
        да хорошее продолжение, так держать =)
        • +2
          У меня Float меню при скроле глючит. У левого меня шапка иногда пропадает.
          • 0
            Да, действительно — увидал сей бажок…
            … в ближайшее время постараюсь пофиксить
            • 0
              Для информации.
              Шапка пропадает в браузерах op9.52/ie7/ff3/chrome
              В опере плюс к этому левый бар не всплывает при скроллинге
              • 0
                Я когда на оф. сайте jQuery примеры к UI-шной либе смотрел, у меня драг'н'дроп элементы улетали при вытаскивании за зону контейнера и атоскроллинге контейнера. С этим примером тот же цирк.

                У меня опера 12.12

                Как-то совсем это печально. Драг элементами надо пользоваться очень аккуратно >_<
          • +1
            Статья хорошая, аккуратно написана, хорошо оформлена, но не вина автора в том, что на хабре нет парсера кода с подсветкой…
            А это же так легко!
            Всего один класс — причем очень небольшой.
            • 0
              самое интересное, что он есть: крайне убогий и кривой :)
            • +2
              Менюшки прикольные, но, по-моему, такого рода меню только чисто поиграться и всё. На серьезных проектах такие меню врядли кто будет использовать. По-моему, если надо использовать выпадающее меню, то лучше его делать на CSS (+маленький скриптик для ИЕ6).
              • 0
                Не всегда есть возможность сделать меню на CSS, зависит от лейаута.
              • 0
                Хорошая статья для дизайнеров, теперь то мы знаем, что это совсем не сложно, и не «ооо, ты лучше по-другому придумывай!»!
                • 0
                  Отчасти ты прав, натолкнулся на такой вот сайтик — www.webdesignerwall.com/tutorials/jquery-tutorials-for-designers/, кое-что оттуда честно скоммуниздено…
                  • 0
                    Если чуть-чуть почитать первую часть статьи, то можно заметить, что она является лишь переводом приведенной ссылки…
                    • 0
                      Ну я это и так знаю, поэтому не читал, а просто пробежал глазами, сорри если обидел.
                • +1
                  Отличная статья, респект вам в карму! :)
                  • 0
                    Спасибо, добавил в избранное, буду использовать =)
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        Отличные статьи. Спасибо.
                        • НЛО прилетело и опубликовало эту надпись здесь
                          • 0
                            а я думал где видел такую же тему… поискал в закладках… точно anton.shevchuk.name/javascript/jquery-for-beginners-2/ потом посмотрел на автор AntonShevchuk :-) респект за инфу
                            в недалеком прошлом твоя первая часть помогла в изучении jQuery. спасибо большое
                            • 0
                              Drop-down меню не работает. Когда мышку к подменю медленно ведешь, они пропадают.
                              • 0
                                этттто еще фигня
                                попробуй в вертикальном дроп-дауне навести мышку на пункт подменю до того, как оно полностью вылезет. прячется, да?
                                а теперь сделай то же самое и мышку с пункта подменю не убирай. наблюдай вечный двигатель!

                                (это на фаерфоксе 3.0.1)

                                но примеры хорошие, мне понравились. да и статья с написана с использованием мозга, что нечасто встретишь.
                              • 0
                                $('...').hover(
                                function() {

                                },
                                function() {

                                }
                                );
                                не работает в ІЕ 6 но можна заменить на:

                                $('...').mouseover(function(){

                                });

                                $('...').mouseout(function(){

                                });
                                • 0
                                  Очень помогло, спасибо большое. Но всё таки IE(6,7) — губители j-красоты :-( В IE7 выпадающее вертикальное меню работает очень плохо.
                                  • 0
                                    В drop-down меню не предусмотрен хак к глюку с в линейке IE-шников?
                                    В случае slideUp и slideDown, нужно лишить пользователя закрыть меню до того как оно полностью не выехало (и наоборот). Лечиться с помощью setTimeout, setInterval.
                                    • 0
                                      под глюком имелось ввиду то что в IE select перекрывается только с помощью ифрейма

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.