繁体   English   中英

如何使用JavaScript中的悬停事件遍历大型菜单?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM