Вход

Просмотр полной версии : Меню-аккордеон. Как сворачивать неактывные пункты?


dmk
05.09.2015, 19:22
Как в меню-аккордеоне делается сворачивание неактивных пунктов меню? Чтобы один открываешь, а прежде открытый закрывался.

Страница с меню: http://dmink.ru/learn/

Код JS:


var btnMenu = document.querySelectorAll('.btn-menu'),
subMenu = document.querySelectorAll('.sub-menu'),
i, btn, sub;

for (i = 0; i < btnMenu.length; i++) {
btn = btnMenu[i];
sub = subMenu[i];

btn.addEventListener('click', menuOpen(btn, sub));
};

function menuOpen(btn, sub) {
return function (event) {
event.preventDefault();
btn.classList.toggle('btn-menu--active');
sub.classList.toggle('sub-menu--show');
};
};


Код HTML:


<ul class="accordeon">

<li><a class="btn-menu" href="#">Верхний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Первое меню 1</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 2</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 3</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 4</a></li>
</ul>
</li>

<li><a class="btn-menu" href="#">Средний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Второе меню 1</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 2</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 3</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 4</a></li>
</ul>
</li>

<li><a class="btn-menu" href="#">Нижний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Третье меню 1</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 2</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 3</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 4</a></li>
</ul>
</li>

</ul>


Без jQuery нужно решение

Vlasenko Fedor
05.09.2015, 21:08
Без jQuery нужно решение
Решение без скриптов :haha:
http://jsfiddle.net/vlasenkofedor/zQ6ae/
Решение на js
http://jsfiddle.net/vlasenkofedor/jLprM/

Decode
05.09.2015, 21:36
<style>
.sub-menu {
display: none;
}
</style>
<ul class="accordeon">
<li><a class="btn-menu" href="#">Верхний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Первое меню 1</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 2</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 3</a></li>
<li><a class="sub-menu__item" href="#">Первое меню 4</a></li>
</ul>
</li>

<li><a class="btn-menu" href="#">Средний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Второе меню 1</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 2</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 3</a></li>
<li><a class="sub-menu__item" href="#">Второе меню 4</a></li>
</ul>
</li>

<li><a class="btn-menu" href="#">Нижний пункт</a>
<ul class="sub-menu">
<li><a class="sub-menu__item" href="#">Третье меню 1</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 2</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 3</a></li>
<li><a class="sub-menu__item" href="#">Третье меню 4</a></li>
</ul>
</li>
</ul>

<script>
var ul = document.querySelector('.accordeon'),
subMenu = document.querySelectorAll('.sub-menu'), curr;

ul.addEventListener('click', function(e) {
if( !e.target.classList.contains('btn-menu') ) return;

curr = e.target.parentNode.querySelector('.sub-menu');

curr.style.display = curr.offsetHeight ? 'none' : 'block';

[].forEach.call(subMenu, function(item) {
if(item == curr) return;
item.style.display = 'none';
});

e.preventDefault();
});
</script>

рони
05.09.2015, 22:15
dmk,
var btnMenu = document.querySelectorAll('.btn-menu'),
subMenu = document.querySelectorAll('.sub-menu'),
i, btn, sub;



for (i = 0; i < btnMenu.length; i++) {
btn = btnMenu[i];
btn.addEventListener('click', menuOpen(i));
};

function menuOpen(i) {
return function (event) {
event.preventDefault();
[].forEach.call( btnMenu , function(el,a) {
a == i ? (el.classList.toggle('btn-menu--active'), subMenu[a].classList.toggle('sub-menu--show')) : (el.classList.remove('btn-menu--active'), subMenu[a].classList.remove('sub-menu--show'));
});

};
};

dmk
05.09.2015, 23:09
рони, Decode, Спасибо. Смотрю, разбираюсь как работает. В нижнем варианте функция как-то громоздко выглядит

Vlasenko Fedor
06.09.2015, 00:59
В нижнем варианте функция как-то громоздко выглядит

document.querySelector('.accordeon').addEventListe ner('click', function (event) {
var element = event.target;
if (element.classList.contains('btn-menu')) {
event.preventDefault();
element.classList.toggle('btn-menu--active');
element.nextElementSibling.classList.toggle('sub-menu--show');
}
});
Уменьшить код можно еще если класс active задавать li? переделав разметку css
Менять класс только одному єлементу