Вертикальное меню аккордеон на jQuery

jQuery & JavaScript WordSmall

аккордеон меню

Вертикальное меню, сделанное в стиле аккордеон с несколькими уровнями подменю. В состав использования входит jQuery и подключение шрифта Font Awesome. Он служит набором иконок, которые присутствуют в меню для визуального оформления. Аккордеон меню выполнено в плоском дизайне в пяти различных цветах. В верхнюю область меню так же возможно добавить поисковую строку, как фильтр для категорий.

Посмотреть Demo

Шаг 1-й. Разметка HTML

Обычная разметка с древовидным построением и с наличием тега <i> для вывода иконок. Стоит обратить внимание лишь на один класс во второй строчке кода, класс green(зеленый). Именно этот класс определяет каким цветом будет меню. Чтобы изменить цвет достаточно, к примеру, указать класс red (красный), вместо зеленого. Всего цветов пять: blue (синий), green (зеленый), red (красный), white (белый), black (черный).

<div class="content">
  <div id="jquery-accordion-menu" class="jquery-accordion-menu green">
    <div class="jquery-accordion-menu-header" id="form"></div>
    <ul id="demo-list">
       <li class="active"><a href="#"><i class="fa fa-home"></i>Home </a></li>
      <li><a href="#"><i class="fa fa-glass"></i>Events </a></li>
      <li><a href="#"><i class="fa fa-file-image-o"></i>Gallery </a>
        <span class="jquery-accordion-menu-label">12 </span>
      </li>
      <li><a href="#"><i class="fa fa-cog"></i>Services </a>
        <ul class="submenu">
          <li><a href="#">Web Design </a></li>
          <li><a href="#">Hosting </a></li>
          <li><a href="#">Design </a>
            <ul class="submenu">
              <li><a href="#">Graphics </a></li>
              <li><a href="#">Vectors </a></li>
              <li><a href="#">Photoshop </a></li>
              <li><a href="#">Fonts </a></li>
            </ul>
          </li>
          <li><a href="#">Consulting </a></li>
        </ul>
      </li>
      <li><a href="#"><i class="fa fa-home"></i>System </a></li>
      <li><a href="#"><i class="fa fa-suitcase"></i>Portfolio </a>
        <ul class="submenu">
          <li><a href="#">Web Design </a></li>
          <li><a href="#">Graphics </a>
            <span class="jquery-accordion-menu-label">10 </span>
          </li>
          <li><a href="#">Photoshop </a></li>
          <li><a href="#">Programming </a></li>
        </ul>
      </li>
      <li><a href="#"><i class="fa fa-user"></i>About </a></li>
      <li><a href="#"><i class="fa fa-envelope"></i>Contact </a></li>
    </ul>
    <div class="jquery-accordion-menu-footer">
      Footer
    </div>
  </div>
</div>

Шаг 2-й. Стили оформления CSS

Стилизация всех основный деталей, включая и самого меню.


.jquery-accordion-menu,.jquery-accordion-menu * {
        /*font-family: 'Open Sans',sans-serif;*/
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        outline: 0
}

.jquery-accordion-menu {
        min-width: 260px;
        float: left;
        position: relative;
        box-shadow: 0 20px 50px #333
}

.jquery-accordion-menu .jquery-accordion-menu-footer,.jquery-accordion-menu .jquery-accordion-menu-header {
        width: 100%;
        height: 50px;
        padding-left: 22px;
        float: left;
        line-height: 50px;
        font-weight: 600;
        color: #f0f0f0;
        background: #414956
}

.jquery-accordion-menu ul {
        margin: 0;
        padding: 0;
        list-style: none
}

.jquery-accordion-menu ul li {
        width: 100%;
        display: block;
        float: left;
        position: relative
}

.jquery-accordion-menu ul li a {
        width: 100%;
        padding: 14px 22px;
        float: left;
        text-decoration: none;
        color: #f0f0f0;
        font-size: 13px;
        background: #414956;
        white-space: nowrap;
        position: relative;
        overflow: hidden;
        -o-transition: color .2s linear,background .2s linear;
        -moz-transition: color .2s linear,background .2s linear;
        -webkit-transition: color .2s linear,background .2s linear;
        transition: color .2s linear,background .2s linear
}

.jquery-accordion-menu>ul>li.active>a,.jquery-accordion-menu>ul>li:hover>a {
        color: #fff;
        background: #3b424d
}

.jquery-accordion-menu>ul>li>a {
        border-bottom: solid 1px #3b424d
}

.jquery-accordion-menu ul li a i {
        width: 34px;
        float: left;
        line-height: 18px;
        font-size: 16px;
        text-align: left
}

.jquery-accordion-menu .submenu-indicator {
        float: right;
        right: 22px;
        position: absolute;
        line-height: 19px;
        font-size: 20px;
        -o-transition: transform .3s linear;
        -moz-transition: transform .3s linear;
        -webkit-transition: transform .3s linear;
        -ms-transition: transform .3s linear
}

.jquery-accordion-menu ul ul.submenu .submenu-indicator {
        line-height: 16px
}

.jquery-accordion-menu .submenu-indicator-minus>.submenu-indicator {
        -ms-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -webkit-transform: rotate(45deg);
        transform: rotate(45deg)
}

.jquery-accordion-menu ul ul.submenu,.jquery-accordion-menu ul ul.submenu li ul.submenu {
        width: 100%;
        display: none;
        position: static
}

.jquery-accordion-menu ul ul.submenu li {
        clear: both;
        width: 100%
}

.jquery-accordion-menu ul ul.submenu li a {
        width: 100%;
        float: left;
        font-size: 11px;
        background: #383838;
        border-top: none;
        position: relative;
        border-left: solid 6px transparent;
        -o-transition: border .2s linear;
        -moz-transition: border .2s linear;
        -webkit-transition: border .2s linear;
        transition: border .2s linear
}

.jquery-accordion-menu ul ul.submenu li:hover>a {
        border-left-color: #414956
}

.jquery-accordion-menu ul ul.submenu>li>a {
        padding-left: 30px
}

.jquery-accordion-menu ul ul.submenu>li>ul.submenu>li>a {
        padding-left: 45px
}

.jquery-accordion-menu ul ul.submenu>li>ul.submenu>li>ul.submenu>li>a {
        padding-left: 60px
}

.jquery-accordion-menu ul li .jquery-accordion-menu-label,.jquery-accordion-menu ul ul.submenu li .jquery-accordion-menu-label {
        min-width: 20px;
        padding: 1px 2px 1px 1px;
        position: absolute;
        right: 18px;
        top: 14px;
        font-size: 11px;
        font-weight: 800;
        color: #555;
        text-align: center;
        line-height: 18px;
        background: #f0f0f0;
        border-radius: 100%
}

.jquery-accordion-menu ul ul.submenu li .jquery-accordion-menu-label {
        top: 12px
}

.ink {
        display: block;
        position: absolute;
        background: rgba(255,255,255,.3);
        border-radius: 100%;
        -webkit-transform: scale(0);
        -moz-transform: scale(0);
        -ms-transform: scale(0);
        -o-transform: scale(0);
        transform: scale(0)
}

.animate-ink {
        -webkit-animation: ripple .5s linear;
        -moz-animation: ripple .5s linear;
        -ms-animation: ripple .5s linear;
        -o-animation: ripple .5s linear;
        animation: ripple .5s linear
}

@-webkit-keyframes ripple {
        100% {
                opacity: 0;
                -webkit-transform: scale(2.5)
        }
}

@-moz-keyframes ripple {
        100% {
                opacity: 0;
                -moz-transform: scale(2.5)
        }
}

@-o-keyframes ripple {
        100% {
                opacity: 0;
                -o-transform: scale(2.5)
        }
}

@keyframes ripple {
        100% {
                opacity: 0;
                transform: scale(2.5)
        }
}

/*стили для синего цвета маню*/
.blue.jquery-accordion-menu .jquery-accordion-menu-footer,.blue.jquery-accordion-menu .jquery-accordion-menu-header,.blue.jquery-accordion-menu ul li a {
        background: #4A89DC
}

.blue.jquery-accordion-menu>ul>li.active>a,.blue.jquery-accordion-menu>ul>li:hover>a {
        background: #3e82da
}

.blue.jquery-accordion-menu>ul>li>a {
        border-bottom-color: #3e82da
}

.blue.jquery-accordion-menu ul ul.submenu li:hover>a {
        border-left-color: #3e82da;
        background: #3b3b3b;
}
/*конец*/

/*стили для зеленого цвета маню*/
.green.jquery-accordion-menu .jquery-accordion-menu-footer,.green.jquery-accordion-menu .jquery-accordion-menu-header,.green.jquery-accordion-menu ul li a {
        background: #03A678
}

.green.jquery-accordion-menu>ul>li.active>a,.green.jquery-accordion-menu>ul>li:hover>a {
        background: #049372
}

.green.jquery-accordion-menu>ul>li>a {
        border-bottom-color: #049372
}

.green.jquery-accordion-menu ul ul.submenu li:hover>a  {
        border-left-color: #049372;
        background: #3b3b3b;
}

/*конец*/

/*стили для красного цвета маню*/
.red.jquery-accordion-menu .jquery-accordion-menu-footer,.red.jquery-accordion-menu .jquery-accordion-menu-header,.red.jquery-accordion-menu ul li a {
        background: #ED5565
}

.red.jquery-accordion-menu>ul>li.active>a,.red.jquery-accordion-menu>ul>li:hover>a {
        background: #DA4453
}

.red.jquery-accordion-menu>ul>li>a {
        border-bottom-color: #DA4453
}

.red.jquery-accordion-menu ul ul.submenu li:hover>a {
        border-left-color: #DA4453;
        background: #3b3b3b;
}
/*конец*/

/*стили для белого цвета маню*/
.white.jquery-accordion-menu .jquery-accordion-menu-footer,.white.jquery-accordion-menu .jquery-accordion-menu-header,.white.jquery-accordion-menu ul li a {
        background: #fff;
        color: #555
}

.white.jquery-accordion-menu>ul>li.active>a,.white.jquery-accordion-menu>ul>li:hover>a {
        background: #f0f0f0
}

.white.jquery-accordion-menu>ul>li>a {
        border-bottom-color: #f0f0f0
}

.white.jquery-accordion-menu ul ul.submenu li:hover>a {
        border-left-color: #f0f0f0;
        background: #3b3b3b;
}

.white.jquery-accordion-menu ul ul.submenu li a {
        color: #f0f0f0
}

.white.jquery-accordion-menu>ul>li>a>.ink {
        background: rgba(0,0,0,.1)
}
/*конец*/

/*стили для черного цвета маню*/
.black.jquery-accordion-menu .jquery-accordion-menu-footer,.black.jquery-accordion-menu .jquery-accordion-menu-header,.black.jquery-accordion-menu ul li a {
        background: #292929
}

.black.jquery-accordion-menu>ul>li.active>a,.black.jquery-accordion-menu>ul>li:hover>a {
        background: #222
}

.black.jquery-accordion-menu>ul>li>a {
        border-bottom-color: #222
}

.black.jquery-accordion-menu ul ul.submenu li:hover>a {
        border-left-color: #222;
        background: #3b3b3b;
}
/*конец*/

.content{
        width:260px;/*ширина меню*/
        margin:100px auto;
}

/*стили поисковой строки*/
.filterinput{
        background-color:rgba(249, 244, 244, 0);
        border-radius:15px;
        width:90%;
        height:30px;
        border:thin solid #FFF;
        text-indent:0.5em;
        font-weight:bold;
        color:#FFF;
}
/*конец*/
#demo-list a{
        overflow:hidden;
        text-overflow:ellipsis;
        -o-text-overflow:ellipsis;
        white-space:nowrap;
        width:100%;
}
                

Шаг 3-й. jQuery

На третьем шаге подключаем скрипты и библиотеку jQuery. Последний скрипт добавит в меню поисковую строку, она служит как фильтр разделов. Если она вам не нужна, то просто удалите этот скрипт из подключения.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript">
; (function($, window, document, undefined) {
    var pluginName = "jqueryAccordionMenu";
    var defaults = {
        speed: 300,
        showDelay: 0,
        hideDelay: 0,
        singleOpen: true,
        clickEffect: true
    };
    function Plugin(element, options) {
        this.element = element;
        this.settings = $.extend({},
        defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init()
    };
    $.extend(Plugin.prototype, {
        init: function() {
            this.openSubmenu();
            this.submenuIndicators();
            if (defaults.clickEffect) {
                this.addClickEffect()
            }
        },
        openSubmenu: function() {
            $(this.element).children("ul").find("li").bind("click touchstart",
            function(e) {
                e.stopPropagation();
                e.preventDefault();
                if ($(this).children(".submenu").length > 0) {
                    if ($(this).children(".submenu").css("display") == "none") {
                        $(this).children(".submenu").delay(defaults.showDelay).slideDown(defaults.speed);
                        $(this).children(".submenu").siblings("a").addClass("submenu-indicator-minus");
                        if (defaults.singleOpen) {
                            $(this).siblings().children(".submenu").slideUp(defaults.speed);
                            $(this).siblings().children(".submenu").siblings("a").removeClass("submenu-indicator-minus")
                        }
                        return false
                    } else {
                        $(this).children(".submenu").delay(defaults.hideDelay).slideUp(defaults.speed)
                    }
                    if ($(this).children(".submenu").siblings("a").hasClass("submenu-indicator-minus")) {
                        $(this).children(".submenu").siblings("a").removeClass("submenu-indicator-minus")
                    }
                }
                window.location.href = $(this).children("a").attr("href")
            })
        },
        submenuIndicators: function() {
            if ($(this.element).find(".submenu").length > 0) {
                $(this.element).find(".submenu").siblings("a").append("<span class='submenu-indicator'>+</span>")
            }
        },
        addClickEffect: function() {
            var ink, d, x, y;
            $(this.element).find("a").bind("click touchstart",
            function(e) {
                $(".ink").remove();
                if ($(this).children(".ink").length === 0) {
                    $(this).prepend("<span class='ink'></span>")
                }
                ink = $(this).find(".ink");
                ink.removeClass("animate-ink");
                if (!ink.height() && !ink.width()) {
                    d = Math.max($(this).outerWidth(), $(this).outerHeight());
                    ink.css({
                        height: d,
                        width: d
                    })
                }
                x = e.pageX - $(this).offset().left - ink.width() / 2;
                y = e.pageY - $(this).offset().top - ink.height() / 2;
                ink.css({
                    top: y + 'px',
                    left: x + 'px'
                }).addClass("animate-ink")
            })
        }
    });
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options))
            }
        });
        return this
    }
})(jQuery, window, document);
</script>

<script type="text/javascript">
//обработчик
        jQuery(document).ready(function () {
                jQuery("#jquery-accordion-menu").jqueryAccordionMenu();
                
        });
//активный класс
        $(function(){        
                $("#demo-list li").click(function(){
                        $("#demo-list li.active").removeClass("active")
                        $(this).addClass("active");
                })        
        })        
</script>
<script type="text/javascript">
//поисковая строка
(function($) {
function filterList(header, list) {
  var form = $("<form>").attr({
    "class":"filterform",
    action:"#"
  }), input = $("<input>").attr({
    "class":"filterinput",
    type:"text"
  });
  $(form).append(input).appendTo(header);
  $(input).change(function() {
    var filter = $(this).val();
    if (filter) {
      $matches = $(list).find("a:Contains(" + filter + ")").parent();
      $("li", list).not($matches).slideUp();
      $matches.slideDown();
    } else {
      $(list).find("li").slideDown();
    }
    return false;
  }).keyup(function() {
    $(this).change();
  });
}
$(function() {
  filterList($("#form"), $("#demo-list"));
});
})(jQuery);
</script>

Скачать исходник

Источник: https://codepen.io/kukulza/pen/vmreYR

Автор, он же Андрей, он же Admin, он же WordSmall

Лентяй-любитель, окончил высшую школу безделья с многочисленными знаками отличия. Создатель этого небольшого «чудо-блога» о еще более «чудном» контенте.

E-mail Google+ Twitter
Комментариев: 13
  • Йцукен

    Подскажите, пожалуйста, как сделать что бы при загрузке страницы, определенный пункт меню оставался открытым и выделенным? Это вообще реально с данным меню?

    • WordSmall

      Добавьте просто стиль блок к определенному субменю, вот так <ul class="submenu" style="display: block;">. Должно работать.

      • Йцукен

        WordSmall, Спасибо! Работает.

  • sanya

    Крутое меню. Очень понравилось. Спасибо!

    Но есть одна проблемка. На мобилках невозможно пролистать меню, срабатывает клик. То есть когда проводишь пальцем мимо пунктов меню срабатывает переход по пункту меню. Как исправить?

    • WordSmall

      Должно быть связано с эффектом клика. Или может даже не дружит с каким-то браузером. Извиняюсь, но нет времени это проверить.

  • sanya

    Может кому пригодится это все из-за touchstart

  • max

    Копировал данный код вертикального меню аккордеон на jQuery в отдельный html — всё работает. Если вставляю на сайт, то не работает: не раскрываются меню, иконок слева нет, справа «+» тоже нет, блок списка сдвигается относительно всего блока.

    С чем это может быть связано и как можно решить?

    • WordSmall

      Иконки — это шрифт Awesome. В статье говорится, что нужно его подключение. Меню может не работать из-за несовместимости с версией библиотеки jQuery или разногласия, если подключаете их несколько.

      • max

        WordSmall, как же совместить?

        Иконки поправил заработали. Но не раскрывается ничего.

  • WordSmall

    Вы подключаете библиотеку из статьи? Кроме нее есть еще подключенные библиотеки jQuery? Достаточно одной. Попробуйте поменять место подключения (header, footer).

  • max

    WordSmall, получилось, с горем по-полам, но точно не из-за места подключения скрипта. Спасибо за ответы и статью.

  • VerbAlexVlad

    Меню классное, но правда, вопрос очень важный и остается открытым. Как листать на мобилках? Сразу кликает при свайпе пальцем... Что делать? Как быть?

    • WordSmall

      Попробуйте изменить это touchstart на это touch

Добавить комментарий
bold quote code