@boga-net

Как верстать такое меню?

Здравствуйте. Давно пытаюсь повторить такое меню - https://www.templatemonster.com/ru/demo/62274.html
И по сей день способы реализации являются для меня загадкой. Может быть кто-нибудь подкинет пару идей ? Я не прошу что-то делать, просто дать подсказку, направление.
Наверняка здесь не обошлось без плагинов, но мне интересно понять, как делается такое меню и уметь повторить

Казалось бы - ну обычное многоуровневое дропдаун меню, в чём проблема ?

Проблема вот в чём :

(ссылка - элемент, который видим в основном меню, при наведении на который, появляется выпадающее меню)

1. Меню при покидании курсора ссылки, скрывается с задержкой. Без задержки на чистом css сделать не сложно. И эту задержку тоже не сложно сделать. Я реализовал это таким образом :

// Выпадающее меню
.dropdown-menu {
transition-delay: 1s

// Выпадающее меню при наведении на ссылку-родителя
.drop-link:hover .dropdown-menu
transition-delay:  0.1s


Таким образом, мы получаем почти мгновенное отображение меню при наведении на ссылку и задержку перед его исчезновением. Может есть способы получше, но я додумался только до такого

Но здесь возникает проблема: если мы наведём на одну ссылку (появится дропдаун меню), и сразу же на другую, то первое не успеет скрыться (из-за задержки) и на экране мы увидим два выпадающих меню. Отказываться от задержки не хочу, потому что всё это опыт, изучение, скилл. Кто-то же делает это. Да, у кого-то больше опыта, но всё можно повторить, главное понять как. Видимо здесь какое-то условие на js :
"если навёл на одну ссылку и не навёл на другую - есть задержка."
"Если навёл на другую ссылку после наведения на предыдущую ссылку - убрать задержку".
Прошу прощения, что так описал условия, но здесь именно концепция

Скрыть первое без задержки (transition-delay) без использования скриптов, как я думаю - невозможно. Тут явное присваивание классов через скрипты для всей ссылки с его выпадающим меню (так как стиль при наведении у ссылки сохраняется, если курсор будет на выпадающем меню). Поправьте, пожалуйста, если я ошибаюсь.

2. Среди прочих выпадающих меню есть одно большое, занимающее по ширине всю страницу
Обычно я верстаю так : Ссылка имеет position: relative, а выпадающее - position: absolute. Таким образом, каждое выпадающее меню выбивается из общего потока ul > li и располагается относительно каждой ссылки. Ок - не проблема. Но как сделать мегаменю, шириной на всю страницу, которое так же находится в общем потоке и не вынесено отдельно за первые nav > ul > li > ul ?

Тут уже position: absolute не прокатит, так как каждое выпадающее меню будет располагаться относительно своего родителя с position: relative. И мегаменю можно подвинуть только используя какие-нибудь отрицательные значения, типа transform: translateX() или left: -300px. Но это не практично, потому что нужно будет постоянно подбирать эти значения. Это не вариант.
Подумав, я пришёл ко мнению, что никакие position: absolute тут не используются и всё делается с помощью javascript. Прав ли я ?

Кто-нибудь когда-нибудь делал такое меню ? Поделитесь опытом, пожалуйста, или советом, каким именно образом вы его верстали ? Нужна общая концепция написания кода, типа :
- это точно без абсолютов,
- точно на js,
- точно плагины,
- да это и с css можно
- .. ваши вариант

Уважаемые, учтите, что речь идёт о точной копии такого меню и задержка перед исчезновением выпадающего меню, как и быстрое исчезновение одного выпадающего меню при появлении другого - имеют ключевое значение. Просьба не скидывать банальные примеры с типичными многоуровневыми меню, без учётов вышеперечисленных нюансов. Спасибо за понимание.
  • Вопрос задан
  • 762 просмотра
Решения вопроса 1
potapchino
@potapchino
spoiler
1. В данном примере анимация сделана на css (css-transition):
.dropdown {
  transition: all .3s ease;
}


2. У каждого dropdown два состояния:
А) dropdown скрыт:
.dropdown {
  opacity: 0;
  visibility: hidden;
  transform: translateY(30px);
}

Б) dropdown видим:
opacity: 1;
  visibility: visible;
  transform: translateY(0px);


3. Когда на одном из пунктов меню генерируется событие mouseover, на него вешается класс focus, который инициирует переход А --> Б:
menuitem.mouseover(function(){
  this.addClass('focus');
});

.menuitem.focus > .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0px);
}


4. Соответсвенно, при наступлении события mouseout, этот класс удаляется, причем не сразу, а с задержкой в 300мс, после чего инициируется переход Б --> А:
menuitem.mouseout(function(){
  id = setTimeout(function(){
    this.removeClass(focus);
  }, 300);
});


5. Если вы наводите курсор на очередной пункт меню, а dropdown предыдущего пункта еще не спрятался (т.к. еще не истекла задеркжка в 300мс), происходит форсированное убирание класса focus с предыдущего пункта меню, в этом случае п. 3 можно переписать следующим образом:
function forceRemoveClass() {
  window.clearInterval(id);
  prevMenuitem.removeClass('focus');
}
...
menuitem.mouseover(function(){
  forceRemoveClass(); 
  this.addClass('focus');
});
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
LenovoId
@LenovoId
svg, css,js
у меня вообще ни какого меню нету там
5b37a23952165390666056.png
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы