Закрывать выпадающее меню при клике на соседний пункт меню

742
24 ноября 2016, 10:02

Есть менюшка на 3 пункта, каждый из которых - выпадающий. По клику на пункт меню появляется выпадающее меню. Но проблема в том, что я могу открыть несколько таких меню одновременно, а мне нужно, чтобы они открывались по очереди. И в случае, если одно подменю уже открыто, то по клику на соседний пункт меню подменю скрывалось. Функция открытия подменю:

$(function() {
    var touch = $('li .menu-link');
    var w = $(window).width();
    $(touch).on('click', function(e) {
        e.preventDefault();
        var menu = $(this).closest('li').find('.dropdown-list');
        menu.slideToggle(0);
    });
    $(window).resize(function(){
        var menu = $('li .menu-link ~ .dropdown-list');
        if(w > 992 && menu.is(':hidden')) {
            menu.removeAttr('style');
        }
    });
});

HTML:

<ul class="menu-item-list desktop-menu">
    <li>
        <a href="#" class="menu-link drop-down">Билеты</a>
        <div class="dropdown-list">
            <div class="menu-items">
                <a href="#"><i style="color: #ff6f00;" class="material-icons">whatshot</i>Спецпредложения</a>
                <a href="#"><i style="color: #ffb300;" class="material-icons">star_rate</i>Популярные рейсы</a>
            </div>
        </div>
    </li>
    <li>
        <a href="#" class="menu-link drop-down">Информация</a>
        <div class="dropdown-list">
            <div class="menu-items">
                <a href="#"><i style="color: #0277bd;" class="material-icons">airplanemode_active</i>Авиакомпании</a>
                <a href="#"><i style="color: #f44336;" class="material-icons">place</i>Аэропорты</a>
            </div>
        </div>
    </li>
    <li>
        <a href="#" class="menu-link drop-down">Компания</a>
        <div class="dropdown-list">
            <div class="menu-items">
                <a href="#"><i style="color: #8bc34a;" class="material-icons">info</i>О нас</a>
                <a href="#"><i style="color: #1565c0;" class="material-icons">help</i>Поддержка</a>
                <a href="#"><i style="color: #607d8b;" class="material-icons">email</i>Контакты</a>
            </div>
        </div>
    </li>
    <li><a href="#" class="menu-link profile-link"><i class="material-icons">person</i>Личный кабинет</a></li>
</ul>
Answer 1

Алгоритм такой: сначала нужно закрыть все подменю slideUp(), а потом если "кликнутое" меню было закрыто, открыть его - slideDown()

$(function() { 
  var touch = $('li .menu-link'); 
  var menuWrapper = $('.menu-item-list'); 
  var w = $(window).width(); 
 
  $('html').click(function() { 
    menuWrapper.find('.dropdown-list').slideUp(0); 
  }); 
 
  menuWrapper.click(function(e) { 
    e.stopPropagation(); 
  }); 
 
  $(touch).on('click', function(e) { 
    e.preventDefault(); 
    var menu = $(this).closest('li').find('.dropdown-list'); 
    var isClosed = menu.is(':hidden'); // закрыто ли подменю, по которому кликнули 
 
    menuWrapper.find('.dropdown-list').slideUp(0); // закрываем все подменю 
 
    // если меню было закрыто, то открываем его 
    if (isClosed) { 
      menu.slideDown(0); 
    } 
  }); 
 
  // ... 
});
<div>outside</div> 
<ul class="menu-item-list desktop-menu"> 
  <li> 
 
    <a href="#" class="menu-link drop-down">Билеты</a> 
    <div class="dropdown-list"> 
      <div class="menu-items"> 
        <a href="#"><i style="color: #ff6f00;" class="material-icons">whatshot</i>Спецпредложения</a> 
        <a href="#"><i style="color: #ffb300;" class="material-icons">star_rate</i>Популярные рейсы</a> 
      </div> 
    </div> 
  </li> 
  <li> 
    <a href="#" class="menu-link drop-down">Информация</a> 
    <div class="dropdown-list"> 
      <div class="menu-items"> 
        <a href="#"><i style="color: #0277bd;" class="material-icons">airplanemode_active</i>Авиакомпании</a> 
        <a href="#"><i style="color: #f44336;" class="material-icons">place</i>Аэропорты</a> 
      </div> 
    </div> 
  </li> 
  <li> 
    <a href="#" class="menu-link drop-down">Компания</a> 
    <div class="dropdown-list"> 
      <div class="menu-items"> 
        <a href="#"><i style="color: #8bc34a;" class="material-icons">info</i>О нас</a> 
        <a href="#"><i style="color: #1565c0;" class="material-icons">help</i>Поддержка</a> 
        <a href="#"><i style="color: #607d8b;" class="material-icons">email</i>Контакты</a> 
      </div> 
    </div> 
  </li> 
  <li><a href="#" class="menu-link profile-link"><i class="material-icons">person</i>Личный кабинет</a> 
  </li> 
</ul> 
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

UPD.

Спасибо, всё работает! Ещё вопрос один: а можно сделать так, что если был сделан клик вне dropdown-list, то чтобы он закрывался?

Нужно добавить обработчик кликов на всей странице $('html').click(/*...*/), в котором закрывать все открытые меню. Но если мы работаем в самом меню, то вызывать e.stopPropagation(); - останавливает "всплытие" вызова события к родительским элементам. Вызывать нужно в событии, где не нужно "принудительно" закрывать меню (например внутри .menu-item-list).

READ ALSO
div multiselect

div multiselect

Здравствуйте!.

350
Phonegap, JQuery Searchable DropDown Plugin in IOS

Phonegap, JQuery Searchable DropDown Plugin in IOS

Доброе время суток !.

356
Шаблон ввода телефона

Шаблон ввода телефона

Использую такую библиотеку jquery. inputmask.

412