尝试模拟MacOS下拉行为

时间:2017-05-12 21:00:23

标签: jquery html twitter-bootstrap

我正在尝试使用Bootstrap和jQuery重新创建MacOS中的下拉列表行为。所需行为在点击时显示/隐藏,但在下拉列表之间移动时也显示悬停,直到再次点击一个。

我已经用一些匆忙编写的jQuery实现了大部分所需的行为:

$(document).ready(function() {
    $(".dropdown").on("click", function(event){
        $('.dropdown').addClass('show-on-hover');
    });

    $('.nav').on('mouseenter', 'li.show-on-hover', function() {
        $('.dropdown.open').removeClass('open');
        $(this).addClass('open');
    });

    $('.nav').on('click', 'li.show-on-hover.open', function() {
        $('.dropdown').removeClass('show-on-hover');
    });
});

但是我遇到了一个问题,如果我点击下拉列表外部,其他人仍然会在悬停时激活(这不应该发生,他们只应该在点击时重新打开)。有关如何解决此问题的任何建议,和/或有关此类下拉行为的更好解决方案的建议将不胜感激!

例如,如果只使用CSS就可以实现这种行为,那就太棒了!

https://codepen.io/jakatz/pen/NjMgRg

1 个答案:

答案 0 :(得分:1)

逻辑实际上非常简单:你只需要使用双点击绑定模式来实现你想要的行为:

  1. 听取.dropdown上的点击事件并启用show-on-hover效果,但阻止它冒泡/传播DOM树,以免它干扰#2。只需拨打event.stopPropagation()
  2. 即可完成此操作
  3. 收听文档上的点击事件,该事件将用于禁用显示悬停效果
  4. 基本上我们对上述逻辑的处理是:

    1. 每当从下拉列表中发出点击事件时启用show-on-hover
    2. 只要在下拉列表中发出点击事件,就会禁用show-on-hover
    3. 我修改了您的逻辑并添加了其他逻辑,请参阅下面的代码中的概念验证(您可能希望在全屏幕中查看它,因为代码段将显示移动/窄视口视图)。

      $(function() {
        // Allow show on hover when dropdowns are clicked on
        $('.dropdown').on('click', function(event) {
        
          // Allow all dropdowns to show on hover
          $('.dropdown').addClass('show-on-hover');
          
          // Open menu
          $(this).toggleClass('open');
          
          // Prevent click event from bubbling up to document
          event.stopPropagation();
        });
      
        // Disable show on hover when click event is emitted from anywhere else
        $(document).on('click', function(event) {
          $('.dropdown').removeClass('show-on-hover');
        });
      
        // Show on hover behavior
        $('.nav').on('mouseenter', 'li.show-on-hover', function() {
          $('.dropdown.open').removeClass('open');
          $(this).addClass('open');
        });
      });
      <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
      <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
      
      <nav class="navbar navbar-default">
        <div class="container-fluid">
          <!-- Brand and toggle get grouped for better mobile display -->
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Brand</a>
          </div>
      
          <!-- Collect the nav links, forms, and other content for toggling -->
          <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="#">Action</a></li>
                  <li><a href="#">Another action</a></li>
                  <li><a href="#">Something else here</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">Separated link</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">One more separated link</a></li>
                </ul>
              </li>
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="#">Action</a></li>
                  <li><a href="#">Another action</a></li>
                  <li><a href="#">Something else here</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">Separated link</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">One more separated link</a></li>
                </ul>
              </li>
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="#">Action</a></li>
                  <li><a href="#">Another action</a></li>
                  <li><a href="#">Something else here</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">Separated link</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">One more separated link</a></li>
                </ul>
              </li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="#">Action</a></li>
                  <li><a href="#">Another action</a></li>
                  <li><a href="#">Something else here</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="#">Separated link</a></li>
                </ul>
              </li>
            </ul>
          </div>
          <!-- /.navbar-collapse -->
        </div>
        <!-- /.container-fluid -->
      </nav>