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

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

Вертикальное меню, сделанное в стиле аккордеон с несколькими уровнями подменю. В состав использования входит 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

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. Спасибо за меню, автору респект!

    Вопрос: сейчас меню разворачивает и не переходит по ссылке (это правильно), а как сделать чтобы при сворачивании оно так же не переходило по ссылке. Сделать ссылку вида (href="#") для пункта меню у которого есть подгруппа не могу по определенным причинам. Заранее спасибо

    1. Так вроде и так по всем пунктам. Да и в целом, зачем вообще фильтр в таком простом меню.

      1. WordSmall, поиск работает только по первому уровню. При росте меню есть необходимость.

  8. Поиск все равно будет показывать верхний уровень, это же закрытый список.

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *