[英]How can I traverse a mega menu using hover events in JavaScript?
我正在使用HTML,CSS和JavaScript构建大型菜单样式的导航。 请参阅此处的代码笔。 http://codepen.io/anon/pen/bZoBYz
HTML:
<div id="menu">
<div id="menu-wrapper">
<ul>
<li><a id="item-1-button" href="#">Item 1</a></li><li><a href="#">Item 2</a></li><li><a href="#">Item 3</a></li>
</ul>
</div>
</div>
<div id="mega-menu">
<div id="mega-menu-wrapper">
<div id="item-1-menu">
<ul>
<li>Child list item 1</li>
<li>Child list item 2</li>
<li>Child list item 3</li>
</ul>
</div>
</div>
<div>
CSS:
* {
margin: 0px;
padding: 0px;
border: none;
outline: none;
font-family: sans-serif;
}
div#menu {
position: relative;
background: #DDD;
overflow: hidden;
height: 50px;
}
div#menu ul{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
div#menu ul li {
display: inline-block;
}
div#menu ul li a {
text-decoration: none;
padding: 20px;
background: #AAA;
}
div#menu-wrapper {
width: 900px;
margin: auto;
}
div#mega-menu {
height: 200px;
position: relative;
background: #AAA;
display: none;
}
div#mega-menu-wrapper {
width: 900px;
height: 100px;
margin: auto;
}
div#item-1-menu {
position: absolute;
display: none;
padding: 20px;
}
div#item-1-menu ul li {
list-style: none;
}
JavaScript:
var itemOneButton = document.getElementById("item-1-button");
var itemOneMenu = document.getElementById("item-1-menu");
var megaMenu = document.getElementById("mega-menu");
var hoveringItemOne = false;
var hoveringMegaMenu = false;
itemOneButton.addEventListener('mouseover', function() {
hoveringItemOne = true;
changeMenu("item1");
}, true);
itemOneButton.addEventListener('mouseout', function() {
hoveringItemOne = false;
changeMenu();
}, true);
megaMenu.addEventListener('mouseover', function() {
hoveringMegaMenu = true;
changeMenu();
}, true);
megaMenu.addEventListener('mouseout', function() {
hoveringMegaMenu = false;
changeMenu();
}, true);
function changeMenu(menuItem) {
if(menuItem === "item1") {
showItem1Menu()
}
if(hoveringItemOne == false && hoveringMegaMenu == false) {
hideItem1Menu();
}
}
function showItem1Menu() {
megaMenu.style.display = 'block';
itemOneMenu.style.display = 'block';
}
function hideItem1Menu() {
megaMenu.style.display = 'none';
itemOneMenu.style.display = 'none';
}
如果将鼠标悬停在菜单中的项目1,将显示该菜单项的超级菜单。 问题是,当我尝试从菜单项悬停到大型菜单时,即使两者彼此相邻,它也会消失。
我使用布尔变量来控制大型菜单的可见性,因为我最终希望让菜单项1、2、3或更多菜单项起作用。
我还尝试了这种变体,将鼠标悬停在第一个菜单项上时将以下两个变量都设置为true。 -hoveringItemOne-hoveringMegaMenu http://codepen.io/anon/pen/oLGYOE
itemOneButton.addEventListener('mouseover', function() {
hoveringItemOne = true;
hoveringMegaMenu = true;
changeMenu("item1");
}, true);
这种变化的问题是变量hoveringMegaMenu变量的悬浮值受到其子元素的干扰。 如果未触碰出现的超级菜单,则它也将永远存在。
有没有更好的方法来开发像这样的大型菜单? 关键是要能够与超级菜单项内的任何内容进行交互,直到光标离开跨越整个页面整个宽度的超级菜单,或者直到另一个菜单项都被悬停为止为止,这将显示一组新内容。
尝试像这样使用
var itemOneButton = document.getElementById("item-1-button"); var itemOneMenu = document.getElementById("item-1-menu"); var megaMenu = document.getElementById("mega-menu"); var hoveringItemOne = false; itemOneButton.addEventListener('mouseover', function() { hoveringItemOne = true; }); itemOneButton.addEventListener('mouseout', function() { hoveringItemOne = false; }); megaMenu.addEventListener('mouseover', function() { hoveringItemOne = true; }); megaMenu.addEventListener('mouseout', function() { hoveringItemOne = false; }); document.addEventListener('mousemove', function() { if (hoveringItemOne) { megaMenu.style.display = "block"; itemOneMenu.style.display = "block"; } else { megaMenu.style.display = "none"; itemOneMenu.style.display = "none"; } });
* { margin: 0px; padding: 0px; border: none; outline: none; font-family: sans-serif; } div#menu { position: relative; background: #DDD; overflow: hidden; height: 50px; } div#menu ul { position: absolute; top: 50%; transform: translateY(-50%); } div#menu ul li { display: inline-block; } div#menu ul li a { text-decoration: none; padding: 20px; background: #AAA; } div#menu-wrapper { width: 900px; margin: auto; } div#mega-menu { height: 200px; position: relative; background: #AAA; display: none; } div#mega-menu-wrapper { width: 900px; height: 100px; margin: auto; } div#item-1-menu { position: absolute; display: none; padding: 20px; } div#item-1-menu ul li { list-style: none; }
<div id="menu"> <div id="menu-wrapper"> <ul> <li><a id="item-1-button" href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 3</a></li> </ul> </div> </div> <div id="mega-menu"> <div id="mega-menu-wrapper"> <div id="item-1-menu"> <ul> <li>Child list item 1</li> <li>Child list item 2</li> <li>Child list item 3</li> </ul> </div> </div> <div>
这是jsFiddle
希望能帮助到你 :)
我可能会丢失一些内容,但是似乎您可以减少一些代码,甚至省去JavaScript。 签出此代码笔: http ://codepen.io/sheriffderek/pen/XKZpJR?editors=0100
有时,子菜单需要分开(在这种情况下,您需要观看与JavaScript的交互)-但您通常可以将它们分别放在其列表项父级中,并使用以下奇妙的position: relative;
和position: absolute;
关系定位。
<ul class='menu'>
<li>
<a href="">Dirt Nap</a>
<ul class='sub-menu'>
<li><a href="">Heart Felt</a></li>
<li><a href="">Moon Belt</a></li>
<li><a href="">Belted out</a></li>
<li><a href="">Outgoing</a></li>
<li><a href="">Closet Deserter</a></li>
</ul>
</li>
...
(您可以在代码笔中将它们转换为CSS)
ul
list-style: none
margin: 0
padding: 0
.big-ugly-monstrosity
width: 100%
float: left
background: $color
.menu
position: relative
width: 100%
float: left // should be clear-fix
a //
display: block
padding: $pad
&:hover
background: rgba(0,0,0,.1)
li
float: left
> li
//
&:hover
.sub-menu
display: block
&:nth-of-type(2n +2)
.sub-menu // to show stacked sub-menu items...
li //
width: 100%
.sub-menu
display: none
position: absolute
top: 100%
left: 0
width: 100%
background: $highlight
我鼓励您改做这样的事情: http : //codepen.io/sheriffderek/pen/lEghe
我认为,由于我们拥有触摸屏和各种设备,因此悬停/下拉菜单是一个非常糟糕的用户界面。
如果您确实使用JavaScript,则可以将'tabs'及其子菜单与rel='tab1'
或data-tab='1'
并在悬停时获取data-attr并使用它来显示data-sub='1'
与之关联。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.