12

首先,我知道这个帖子:
Activating bootstrap dropdown menu on hover
Bootstrap Dropdown with Hover
How to make twitter bootstrap menu dropdown on hover 而不是 click
和其他的,但仍然没有找到正确的解决方案,这就是我到目前为止所做的.
首先,我使用了 angular-bootstrap 下拉指令中的 is-open 属性,如下所示:

<span class="dropdown" dropdown is-open="status.isopen">
  <a
    href
    class="dropdown-toggle"
    ng-mouseenter="status.isopen = true"
    ng-mouseleave="status.isopen = false"
  >
    hover me for a dropdown with angular-bootstrap
  </a>
  <ul
    class="dropdown-menu"
  >
    <li ng-repeat="choice in items">
      <a href>{{choice}}</a>
    </li>
  </ul>
</span>

这似乎有效,但出现了 2 个错误:

  • 第一个是当点击下拉切换元素时,下拉菜单消失了,再次点击不会把它带回来你必须鼠标离开然后鼠标进入下拉切换以获取下拉菜单。
  • 第二个是css/html问题。

通常下拉菜单的常规 css 解决方案是这样的:

<a class="css-dropdown">
  hover here with css.
  <div class="css-dropdown-menu">
    <p>item 1</p>
    <p>item 2</p>
    <p>item 3</p>
  </div>
</a>

请注意,下拉菜单现在位于下拉切换元素内,这意味着当使用鼠标从下拉切换到下拉菜单时,它正在从父级移动到子级,所以基本上我们仍然将鼠标悬停在下拉切换上,因为我们是在它的孩子中,这意味着下拉菜单仍然可见,另一方面,引导下拉菜单与点击事件一起使用,因此不需要将下拉菜单作为下拉切换的孩子,但现在当有人想要将鼠标离开下拉菜单后的行为更改为 mouseenter/hover-toggle 下拉菜单消失,因此我们不再可以访问下拉菜单元素,这在此plunker中可见

为了修复第一个错误,我刚刚删除了下拉指令,然后将 is-open 替换为 ng-class 指令,如下所示。
改变这个:

<span class="dropdown" dropdown is-open="status.isopen">

对此:

<span class="dropdown" ng-class="{'open': status.isopen}">

其余的保持与修复第一个错误相同的plunker 。
第二个错误很棘手,因为下拉菜单不再是下拉切换的子项,从切换到菜单时悬停效果不会持续,所以我这样做了。改变了这个:

<ul class="dropdown-menu">

对此:

<ul
  class="dropdown-menu"
  ng-mouseenter="status.isopen = true"
  ng-mouseleave="status.isopen = false"
>

这样做了,但是当单击它保持打开状态的下拉菜单项时出现了另一个错误,所以我一直这样做。改变了这个:

<li ng-repeat="choice in items">

对此:

<li ng-repeat="choice in items" ng-click="status.isopen = false">

这给了我所需的行为plunker
也就是说,这不是一个好的解决方案,因为这里涉及很多指令以获得简单的视觉效果,我提供的最后一个 plunker 包含一个不涉及 Bootstrap 或 AngularJS 的 css 解决方案,尽管它是必需的行为,但不是必需的html 结构或视觉结果,我需要的是在下拉切换和下拉菜单之间有一个空格,而不是切换元素的填充只是一个空白,这使得 css 解决方案在这种情况下无效。
所以,我的问题是有没有更好的方法来做到这一点,而无需为悬停下拉菜单添加新的插件/库更干净且易于重用的解决方案?

4

4 回答 4

5

首先,在最顶层的父元素上进行切换(在本例中为<span>

<span class="btn-group" dropdown is-open="status.isopen" ng-mouseenter="status.isopen = true" ng-mouseleave="status.isopen = false">
  <a class="btn btn-primary dropdown-toggle" dropdown-toggle>
    Button dropdown <span class="caret"></span>
  </a>
  <ul class="dropdown-menu" role="menu">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li class="divider"></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</span>

这将允许您想要的行为 - 同时仍然允许单击显示/隐藏菜单;-)

但是有一个烦恼:如果您将鼠标光标移动得较慢并通过切换和菜单之间的小间隙,它将隐藏菜单。

所以其次,添加一个小的CSS来消除差距

.dropdown-menu {
    margin-top: 0;
}

请参阅此plunker中的操作。

于 2015-07-15T09:20:40.173 回答
0

我知道您想要一个解决方案without adding a new plugin/library,但您(或寻求此行为的其他人)可能想尝试使用下拉增强功能库中的 No Close来保持下拉菜单打开,即使在单击其中一个选项后也是如此:

不要在点击收音机添加类时关闭菜单.noclose

<div class="btn-group">
  <button data-toggle="dropdown" class="btn btn-default dropdown-toggle">
      Checked option <span class="caret"></span>
  </button>
  <ul class="dropdown-menu noclose">
      <li>
          <input type="radio" id="gr1_1" name="gr1" value="1">
          <label for="gr1_1">Option 1</label>
      </li>
      <li>
          <input type="radio" id="gr1_2" name="gr1" value="2">
          <label for="gr1_2">Option 2</label>
      </li>
      <li>
          <input type="radio" id="gr1_3" name="gr1" value="3">
          <label for="gr1_3">Option 3</label>
      </li>
  </ul>
</div>

还为悬停问题添加 CSS 解决方案:

.btn-group:hover .dropdown-menu.noclose {
    display: block;
}
.dropdown-menu.noclose {
    margin-top: 0px;
}

当然,不要忘记导入库:


在您的情况下,我建议您研究Dropdown Enhancements 的源代码,看看它是如何工作的,并可能找到更合适的解决方案。

于 2015-03-20T22:54:28.960 回答
0

以下是我在处理同一问题时提出的解决方案。

我使用了一个简单的自定义指令:

  • mouseenter将and事件绑定mouseleave到下拉菜单,以便正确显示/隐藏菜单。
  • 为下拉菜单动态添加自定义 CSS 类,以防止将光标从按钮移动到菜单时菜单消失。请注意,此解决方案的优点是不会消除 button 和 menu 之间的视觉差距
  • 防止单击按钮时菜单消失。

CSS 规则使用before伪元素来填充按钮和菜单之间的空隙。我添加了border可以取消注释的属性,以便轻松获得视觉反馈。

.dropdown-hover-menu::before {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
  top: -3px;
  height: 3px;
  /*border: 1px solid black;*/
}

片段的 HTML 结构基于angular-ui 引导文档的下拉部分中的可用示例

angular.module('app', ['ui.bootstrap'])
  .directive('dropdownHover', function() {
    return {
      require: 'uibDropdown',
      link: function(scope, element, attrs, dropdownCtrl) {

        var menu = angular.element(element[0].querySelector('.dropdown-menu')),
          button = angular.element(element[0].querySelector('.dropdown-toggle'));

        menu.addClass('dropdown-hover-menu');

        element.bind('mouseenter', onMouseenter);
        element.bind('mouseleave', onMouseleave);
        button.bind('click', onClick);

        function openDropdown(open) {
          scope.$apply(function() {
            dropdownCtrl.toggle(open);
          });
        }

        function onMouseenter(event) {
          if (!element.hasClass('disabled') && !attrs.disabled) {
            openDropdown(true);
          }
        };

        function onMouseleave(event) {
          openDropdown(false);
        };

        function onClick(event) {
          event.stopPropagation();
        }

        scope.$on('$destroy', function() {
          element.unbind('mouseenter', onMouseenter);
          element.unbind('mouseleave', onMouseleave);
          button.unbind('click', onClick);
        });
      }
    };
  });
.dropdown-hover-menu::before {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
  top: -3px;
  height: 3px;
  /*border: 1px solid black;*/
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<div ng-app="app">
  <div class="btn-group" uib-dropdown dropdown-hover>
    <button type="button" class="btn btn-primary dropdown-toggle">
      Button dropdown <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" uib-dropdown-menu role="menu">
      <li role="menuitem"><a href="#">Action</a>
      </li>
      <li role="menuitem"><a href="#">Another action</a>
      </li>
      <li role="menuitem"><a href="#">Something else here</a>
      </li>
      <li class="divider"></li>
      <li role="menuitem"><a href="#">Separated link</a>
      </li>
    </ul>
  </div>
</div>

于 2016-07-31T02:05:58.590 回答
0

尝试将此行添加到您的 CSS:

.btn-group:hover>.dropdown-menu { display: block; margin-top: 0; }

您必须删除您的 is-open、ng-mouseenter 和 ng-mouseleave 指令。

于 2016-06-14T04:57:15.863 回答