在jQuery中创建向下滑动子菜单的最有效方法

时间:2015-04-03 12:13:57

标签: javascript jquery html css

当我将鼠标悬停在某个元素上时,我试图创建一个从主菜单栏向下滑动的子菜单。我目前正在使用以下代码执行此操作:

$(document).ready( function() {
  $('.navlist li a').hover( function() {
    if( $(this).attr( 'data-param' ) == "parent" )
    {
      $('#subnavbar-' + $(this).attr( 'data-slug' )).slideDown( 200 );
    }
  }, function() {
    if( $(this).attr( 'data-param' ) == "parent" )
    {
      var name = '#subnavbar-' + $(this).attr( 'data-slug' );
      setTimeout( function() {
        if( !$(name).is(':hover') )
        {
          $(name).slideUp( 200 );
        }
      }, 200 );
    }
  });
});
a {
  color: white;
}

.navbar {
  background-color: green;
  margin-bottom: 0;
  height: 30px;
}

ul.navlist {
  list-style: none;
  text-indent: 0;
  margin: 0;
  padding: 0;
  float: left;
}

ul.navlist li {
  display: block;
  width: 100px;
  float: left;
}

.subnavbar {
  background-color: blue;
  margin-top: 0;
  height: 20px;
  display: none;
}

ul.subnavlist {
  list-style: none;
  text-indent: 0;
  margin: 0;
  padding: 0;
  float: left;
}

ul.subnavlist li {
  display: block;
  width: 80px;
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar">
  <ul class="navlist">
    <li><a href="#">Item 1</a></li>
    <li><a href="#" data-param="parent" data-slug="test">Hover Here</a></li>
    <li><a href="#">Item 3</a></li>
  </ul>
</div>

<div class="subnavbar" id="subnavbar-test">
  <ul class="subnavlist">
    <li><a href="#">Subitem 1</a></li>
    <li><a href="#">Subitem 2</a></li>
    <li><a href="#">Subitem 3</a></li>
  </ul>
</div>

正如您通过运行代码段所看到的那样;它有效,但有很多错误,我不知道最好的解决方法是什么。首先,如果用户在主菜单项上来回徘徊,我不希望该事件被发送垃圾邮件,我可以使用setTimeout()clearTimeout()解决此问题,但我想要更好如果可能的话。其次,我不知道如果用户将鼠标悬停在其上而不是父菜单项上,我不知道如何最好地使子弹头缩回,我现在如何操作,但如果用户徘徊,导航栏不会缩回。

3 个答案:

答案 0 :(得分:1)

有效的解决方案是使用CSS。绝对不需要JQUERY!试试这个Fiddle

HTML:

<nav>
    <ul>
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a>
            <ul>
                <li><a href="#">Sub Item 1</a></li>
                <li><a href="#">Sub Item 2</a></li>
                <li><a href="#">Sub Item 3</a>
                    <ul>
                        <li><a href="#">Sub Sub Item 1</a></li>
                        <li><a href="#">Sub Sub Item 2</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li><a href="#">Item 3</a>
            <ul>
                <li><a href="#">Sub Item 1</a></li>
                <li><a href="#">Sub Item 2</a></li>
            </ul>
        </li>
    </ul>
</nav>

CSS代码:

nav {
    margin: 100px auto;
    text-align: center;
}
nav ul ul {
    display: none;
}
nav ul li:hover > ul {
    display: block;
}
nav ul {
    background: -moz-linear-gradient(center top , #efefef 0%, #bbbbbb 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
    border-radius: 10px;
    box-shadow: 0 0 9px rgba(0, 0, 0, 0.15);
    display: inline-table;
    list-style: outside none none;
    padding: 0 10px;
    position: relative;
}
nav ul::after {
    clear: both;
    content: "";
    display: block;
}
nav ul li {
    float: left;
}
nav ul li:hover {
    background: -moz-linear-gradient(center top , #4f5964 0%, #5f6975 40%) repeat scroll 0 0 rgba(0, 0, 0, 0);
}
nav ul li:hover a {
    color: #fff;
}
nav ul li a {
    color: #757575;
    display: block;
    padding: 15px 20px;
    text-decoration: none;
}
nav ul ul {
    background: none repeat scroll 0 0 #5f6975;
    border-radius: 0;
    padding: 0;
    position: absolute;
    top: 100%;
}
nav ul ul li {
    border-bottom: 1px solid #575f6a;
    border-top: 1px solid #6b727c;
    float: none;
    position: relative;
}
nav ul ul li a {
    color: #fff;
    padding: 5px 10px;
}
nav ul ul li a:hover {
    background: none repeat scroll 0 0 #4b545f;
}
nav ul ul ul {
    left: 100%;
    position: absolute;
    top: 0;
}

答案 1 :(得分:1)

正如你告诉我更好的css我为你做了一个快速 fiddle

当然,你需要改进风格,但是&#34;工作&#34;在那里。

css:

    .container {
    height:30px;
    background-color:green;
    color:#fff;
}
.container > ul {position:relative;}
.container > ul li {
    display:inline-block;
    margin-right:30px;
}
.container > ul >li > ul {
    position:absolute;
    left:0;
    background-color:blue;
    top:0px;
    z-index:-1;       
}
.container > ul > li:hover > ul {
    top:30px;
    -webkit-transition: all 0.4s ease;
    -moz-transition: all 0.4s ease;
    -ms-transition: all 0.4s ease;
    -o-transition: all 0.4s ease;
    transition: all 0.4s ease;
}

编辑:我改变了方法并且保证了高度过渡的转换我只使用了顶部。检查出来

答案 2 :(得分:0)

解决你的第一个问题我建议使用jQuery插件Hover Intent。顾名思义,这提供了一种简单的方法来确定用户是否打算将鼠标悬停在元素上,并避免通过多次快速悬停进出元素来发送垃圾邮件的可能性。

要解决第二个问题,如果可能的话,您可以在navbar和subnavbar周围添加一个包含元素,并在离开包含元素时使用它来关闭子视点,如果subnavbar恰好可见。

HTML:

<div id="containing_element">
   <div class="navbar">
      <ul class="navlist">
         <li><a href="#">Item 1</a></li>
         <li><a href="#" id="hoverlink">Hover Here</a></li>
         <li><a href="#">Item 3</a></li>
      </ul>
   </div>
   <div class="subnavbar" id="subnavbar-test">
      <ul class="subnavlist">
         <li><a href="#">Subitem 1</a></li>
         <li><a href="#">Subitem 2</a></li>
         <li><a href="#">Subitem 3</a></li>
      </ul>
   </div>
</div>

jQuery的:

$(document).ready( function() {
    function hoverEnter() {
        $('#subnavbar-test').slideDown(200);
    }
    $('#hoverlink').hoverIntent( hoverEnter );
    $('#containing_element').mouseleave(function () {
        if($('#subnavbar-test').is(':visible')) {
            $('#subnavbar-test').slideUp(200);
        }               
    });
});

请记住也包括悬停意图的脚本。