Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.09.2015, 19:22
Аватар для dmk
dmk dmk вне форума
Интересующийся
Отправить личное сообщение для dmk Посмотреть профиль Найти все сообщения от dmk
 
Регистрация: 21.03.2015
Сообщений: 13

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

Страница с меню: 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 нужно решение

Последний раз редактировалось dmk, 05.09.2015 в 20:02.
Ответить с цитированием
  #2 (permalink)  
Старый 05.09.2015, 21:08
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Сообщение от dmk
Без jQuery нужно решение
Решение без скриптов
http://jsfiddle.net/vlasenkofedor/zQ6ae/
Решение на js
http://jsfiddle.net/vlasenkofedor/jLprM/
Ответить с цитированием
  #3 (permalink)  
Старый 05.09.2015, 21:36
Профессор
Отправить личное сообщение для Decode Посмотреть профиль Найти все сообщения от Decode
 
Регистрация: 31.01.2015
Сообщений: 576

<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>

Последний раз редактировалось Decode, 06.09.2015 в 00:37.
Ответить с цитированием
  #4 (permalink)  
Старый 05.09.2015, 22:15
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

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'));
        });

    };
};
Ответить с цитированием
  #5 (permalink)  
Старый 05.09.2015, 23:09
Аватар для dmk
dmk dmk вне форума
Интересующийся
Отправить личное сообщение для dmk Посмотреть профиль Найти все сообщения от dmk
 
Регистрация: 21.03.2015
Сообщений: 13

рони, Decode, Спасибо. Смотрю, разбираюсь как работает. В нижнем варианте функция как-то громоздко выглядит
Ответить с цитированием
  #6 (permalink)  
Старый 06.09.2015, 00:59
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Сообщение от dmk Посмотреть сообщение
В нижнем варианте функция как-то громоздко выглядит
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
Менять класс только одному єлементу

Последний раз редактировалось Vlasenko Fedor, 06.09.2015 в 01:36.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с меню аккордеон masaniachko jQuery 9 17.06.2018 14:25
Меню аккордеон на задержке при событии hover | jQuery Александр О. jQuery 6 09.07.2014 20:44
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 13:29
Вертикальное меню - аккордеон. Проблема. notgosu Events/DOM/Window 5 23.01.2013 11:47
Раскрывающееся меню, как переставить на другую сторону? Resager Events/DOM/Window 8 22.08.2008 21:56