如何使菜单像Stack Overflow一样

时间:2015-03-07 22:17:04

标签: javascript jquery html drop-down-menu

我非常喜欢Stack Overflow在顶部完成下拉菜单的方式。请注意您必须点击以便下拉菜单触发,但您仍然必须悬停才能获得下拉列表。还有什么似乎是组 - 一旦你点击,悬停将激活图片中显示的菜单。很难解释,但如果你玩了一会儿,你会明白我的意思。此外,重要的是最后悬停的菜单会显示,直到用户再次点击为止。

Stack Overflow's Menu System

这是我到目前为止所拥有的;请注意,我几乎具有相同的功能,除了最后一个菜单悬停不会保持掉线(它在鼠标输出时关闭,直到它不应该关闭)并且切换功能是粗略的:

$(document).ready(function() {
  var depressed = false;

  $('.menu').click(function() {
    depressed = true;
    $('.menu').toggleClass('active');
  });
  $('.menu').hover(function() {
    if (depressed) {
      $('.menu').toggleClass('active');
    }
  });
});
ul {
  margin: 0;
  padding: 0;
}
ul li {
  display: inline-block;
  padding: 10px 20px;
  background: #333;
  color: #eee;
}
ul li.active:hover ul {
  display: block;
}
ul li ul {
  display: none;
  position: absolute;
  border: 2px solid #555;
}
ul li ul li {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li class="menu">button 1
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu">button 2
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu">button 3
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
</ul>

我的JS不是cuttin git。 那么,最好的方法是什么?

2 个答案:

答案 0 :(得分:2)

我没有偷看SO菜单,所以我不知道他们是怎么做到的。但这看起来效果很好。

单击其中一个按钮可打开下拉列表。

“鼠标输出”不会关闭下拉列表,就像在代码中一样,但只有在另一个菜单悬停时才会关闭。如果您将鼠标悬停在菜单区域之外,则最后悬停的菜单将保持打开状态。

点击任意位置关闭菜单。

因此,显示菜单不是通过在CSS中使用:hover伪元素直接完成的,而是通过添加一个类,即使菜单未被覆盖也会保留。我认为净结果非常接近Stack Overflow。

$(function(){

  // The event to handle clicks outside of the menu. This will close the menu.
  var offEvent = 
    function(event){
      $('.menu-bar').removeClass('active');
      $(document).off('click', offEvent);
    };

  // The click event on the menu buttons, to toggle 'menu mode' as it were.
  $(document).on('click', '.menu-bar .menu', 
    function(event){
      event.preventDefault();
      $('.menu-bar').addClass('active');
      $(this).addClass('active');
     
      // Leave menu mode by clicking anywhere of the menu.
      $(document).on('click',
        offEvent
        );
    });
  
  // Hover toggles between the dropdowns of the separate menus.
  $('.menu-bar .menu').hover( 
    function(event){
      var $current = $(this);
      $('.menu').each(
        function(index, element){
          var $element = $(this);
          if ($element.get(0) == $current.get(0)) {
            $element.addClass('active');
          } else {
            $element.removeClass('active');
          }
        });
    });
});
ul {
  margin: 0;
  padding: 0;
}

ul li {
  display: inline-block;
  padding: 10px 20px;
  background: #333;
  color: #eee;
}

ul li ul {
  display: none;
  position: absolute;
  border: 2px solid #555;
}

ul li ul li {
  display: block;
}

.menu .dropdown {
  display: none;
}
.menu-bar.active .menu.active .dropdown {
  display: block;
}

.menu {
  display: inline-block;
  position: relative;
  border: 1px solid grey;
}

.menu .dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  border: 2px solid #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu-bar">
  <li class="menu">button 1
    <ul class="dropdown">
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu">button 2
    <ul class="dropdown">
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu">button 3
    <ul class="dropdown">
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
</ul>

答案 1 :(得分:0)

&#13;
&#13;
$(document).ready(function() {

  $('#M1').click(function() {
    $('#M1').toggleClass('active');
    $('#M2').removeClass('active');
    $('#M3').removeClass('active');
  });
  $('#M2').click(function() {
    $('#M2').toggleClass('active');
    $('#M1').removeClass('active');
    $('#M3').removeClass('active');
  });
  $('#M3').click(function() {
    $('#M3').toggleClass('active');
    $('#M1').removeClass('active');
    $('#M2').removeClass('active');
  });
  
});
&#13;
ul {
  margin: 0;
  padding: 0;
}
ul li {
  display: inline-block;
  padding: 10px 20px;
  background: #333;
  color: #eee;
}
ul li.active ul {
  display: block;
}
ul li ul {
  display: none;
  position: absolute;
  border: 2px solid #555;
}
ul li ul li {
  display: block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li class="menu" id='M1'>button 1
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu" id='M2'>button 2
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
  <li class="menu" id='M3'>button 3
    <ul>
      <li>sub button 1</li>
      <li>sub button 2</li>
    </ul>
  </li>
</ul>
&#13;
&#13;
&#13;

这适合我。

我刚刚删除:从.active类的末尾悬停,并为每个按钮创建一个单独的函数。