Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Меню-аккордеон. Как сворачивать неактывные пункты? (https://javascript.ru/forum/misc/58112-menyu-akkordeon-kak-svorachivat-neaktyvnye-punkty.html)

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

Цитата:

Сообщение от dmk
Без 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

Цитата:

Сообщение от dmk (Сообщение 387274)
В нижнем варианте функция как-то громоздко выглядит

document.querySelector('.accordeon').addEventListener('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
Менять класс только одному єлементу


Часовой пояс GMT +3, время: 16:49.