10.10.13, 14:48
0 комментарий
  Уроки

Создаем новое многоуровневое меню Google Play с нуля

Google недавно обновила свой сайт Google Play, и в новом дизайне наше внимание сильно привлекло новое многоуровневое меню навигации. Вдохновившись плавной анимацией и тем, как они позволяют пользователям выбирать разные пункты меню при наведении на кнопки, мы решили создать схожую навигацию с нуля при помощи HTML, CSS и jQuery.

В данном демо мы решили использовать великолепный иконический веб-шрифт под названием Elusive Icons, который был разработан пользователем GitHub под ником aristath, вместо иконок от Google, так что, не забудьте включить этот шрифт и jQuery-библиотеку в ваш проект до того, как приступать к работе.



Разработка многоуровневой навигации

HTML-код

<nav class="navigation">
      <a href="#" class="active home">
        <span class="icon"><i class="icon-home"></i></span> <span class="content">Home</span>
      </a>
      <a href="#app_nav" class="green">
        <span class="icon"><i class="icon-website"></i></span> <span class="content">Apps</span>
      </a>
      <div class="hide second_level" id="app_nav">
        <a href="#" class="back">
          <i class="icon-chevron-left"></i>
        </a>
        <div class="content">
          <a href="http://www.google.com">
           <span class="content">Popular Apps</span>
          </a>
          ….
         </div>
      </div>
      ….
</nav>


HTML-часть довольно ясна. Здесь у нас есть по умолчанию выделенная ссылка с ярлыком Home, которую мы будем использовать для возврата к основному уровню меню. Эта ссылка не будет ничего запускать, если пользователь уже находится на основном уровне навигации, и именно поэтому мы указали значение # в атрибуте hfer. Эта ссылка нужна для того, чтобы пользователи могли возвращаться назад, поэтому не изменяйте и не удаляйте ее.

Вторая ссылка и все, что следует за ней, это ссылки, которые будут переносить пользователя на второй уровень меню. Тег div, смежный ссылке, будет представлять собой скрытый второй уровень меню, который будет появляться только после того, как пользователь кликнет по второй ссылке. Внутри этого скрытого div’а вы можете видеть пустую ссылку под ярлыком “back”. Мы используем ее для того, чтобы пользователь мог вернуться к основному уровню меню или переключаться на остальные части при помощи единого клика.

Вам нужно добавить еще несколько фрагментов меню, чтобы оно представляло собой показанную структуру, и чтобы href корректно указывали на id скрытый div’ов, как было показано выше.

CSS-код

Так как большая часть контроллеров и анимации управляется при помощи JS, вы можете свободно редактировать CSS-части нашего меню.

JS

$(window).load(function () {
  $(".navigation > a").click(function() {
    if (!$(this).hasClass("active")) {
      $(".navigation").unbind('mouseleave');
      $(".navigation .second_level").hide();
      var el = $(this);
      el.addClass("hover");
      $(".navigation > a.active").fadeOut("fast", function() {
        var prev = $(this)
        prev.removeClass('active');
        container_pos = $(".navigation").offset()
        button_pos = el.offset()
        el.animate({ top: container_pos.top - button_pos.top }, 500, function() {
          el.addClass("active").removeClass("hover").css("top", 0);
          if (el.attr("href").length > 1 && el.attr("href") != "#") {
            $(".navigation > a:not(.active)").hide();
            $(el.attr("href")).slideDown("slow");
          } else {
            prev.fadeIn("fast");
          }
        });
      });
    }
     
  });
   
  $(".navigation .back").hover(
    function () {
      var el = $(this)
      $(".navigation .second_level").hide();
      $(".navigation > a").show();
      $(".navigation").hover(function() {}, function() {
        $(this).unbind('mouseleave');
        $(".navigation > a:visible:not(.active)").hide();
        el.closest(".second_level").show();
      });
       
    });
});


JS-часть будет немного сложнее. В целом, мы привязали все ссылки к функции click, а значит, клик пользователя переместит ссылку вверх, скроет основной уровень меню, и покажет нам следующий уровень.

Вторая часть JS используется для того, чтобы привязать все кнопки возврата внутри второго уровня меню. Как только вы наводите курсор на кнопку возврата, основной уровень меню должен на время отобразиться поверх отображенного второго уровня меню, и когда курсор больше не находится поверх ссылки, основной уровень меню должен снова исчезнуть, оставив в поле видимости лишь второй уровень меню.

Хотя это и кажется простым, на самом деле все немного сложнее. Нам нужно определить, как каждая ссылка должна действовать по-отдельности, так как нам нужно, чтобы кнопка Home так же возвращала пользователя на исходную позицию. Мы решили добавить небольшое условие для того, чтобы определять, кликнутая ссылка относится к кнопке Home или нет. Сделать это можно путем проверки атрибута href. Если href будет равно “#”, значит нужно выполнить процедуру возврата, если же нет, то действовать следует в обычном режиме.

При помощи вышеприведенного фрагмента кода, мы можем интегрировать animate.css в наш js, просто вместо него использовав код, а также изменить анимацию, как показано ниже:

В нижеприведенном коде мы видим 2 набора анимации - <<first-level-animation>> и <<second-level-animation>>. Первый нужен для анимации основного уровня меню, когда пользователь наводит курсор на кнопку возврата. Второй необходим для анимации, когда пользователь кликает по меню основного уровня и появляется меню второго уровня.

Вы можете поиграть с этими значениями, используя приведенные значения. К примеру, чтобы получить эффект bounceIn на всех уровнях, измените все указатели <<first-level-animation>> и <<second-level-animation>> в нижеприведенном коде на bounceIn и так далее.

$(window).load(function () {
        $(".navigation > a").click(function() {
          if (!$(this).hasClass("active")) {
            $(".navigation").unbind('mouseleave');
            $(".navigation .second_level").removeClass("animated <<second-level-animation>>").hide(); 
            var el = $(this);
            el.addClass("hover");
            $(".navigation > a.active").fadeOut("fast", function() {
              var prev = $(this)
              prev.removeClass('active');
              container_pos = $(".navigation").offset()
              button_pos = el.offset()
              el.animate({ top: container_pos.top - button_pos.top }, 500, function() {
                el.addClass("active").removeClass("hover").css("top", 0);
                if (el.attr("href").length > 1 && el.attr("href") != "#") {
                  $(".navigation > a:not(.active)").removeClass("<<first-level-animation>> animated").hide();
                  $(el.attr("href")).addClass("<<second-level-animation>> animated").show();
                } else {
                  prev.addClass("<<first-level-animation>> animated").fadeIn("fast");
                }
              });
            });
          }
 
        });
 
        $(".navigation .back").hover(
          function () {
            var el = $(this)
            $(".navigation .second_level").removeClass("animated <<second-level-animation>>").hide();
            $(".navigation > a:not(.active)").addClass("<<first-level-animation>> animated").show()
            $(".navigation").hover(function() {}, function() {
              $(this).unbind('mouseleave');
              $(".navigation > a:visible:not(.active)").hide().removeClass("<<first-level-animation>> animated");
              el.closest(".second_level").addClass("animated <<second-level-animation>>").show();
            });
          });
      });


В заключение

Надеемся, что вам понравилось данное руководство, и вы сможете использовать данный прием в собственных проектах.

Исходники в архиве.

Напишите своё мнение