【问题标题】:How can I modify ui.bootstrap.dropdown to respond to a mouse hover over the drop button?如何修改 ui.bootstrap.dropdown 以响应鼠标悬停在下拉按钮上?
【发布时间】:2016-07-19 03:36:38
【问题描述】:

我想使用 ui.bootstrap.dropdown 消息框以类似于 ui.bootstrap.popover 的方式显示文本信息(不是链接)。我想修改这个指令,因为它完成了我需要的 99%,并且我不想添加弹出框需要的所有额外 JS。

换句话说,我希望当用户将鼠标悬停在向下箭头上时显示“下拉列表区域”,然后当他们将鼠标从向下箭头移开时消失。

有没有一种方法可以向 ui.bootstrap.dropdown 添加一个选项,以便将鼠标悬停在箭头上会显示和隐藏下拉框。我不想在这个框中放置任何链接。

我希望有人有一些想法可以帮助我建议如何更改 ui.bootstrap.dropdown 附带的指令:

.directive('dropdownToggle', function () {
    return {
        require: '?^dropdown',
        link: function (scope, element, attrs, dropdownCtrl) {
            if (!dropdownCtrl) {
                return;
            }

            dropdownCtrl.toggleElement = element;

            var toggleDropdown = function (event) {
                event.preventDefault();

                if (!element.hasClass('disabled') && !attrs.disabled) {
                    scope.$apply(function () {
                        dropdownCtrl.toggle();
                    });
                }
            };

            element.bind('click', toggleDropdown);

            // WAI-ARIA
            element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
            scope.$watch(dropdownCtrl.isOpen, function (isOpen) {
                element.attr('aria-expanded', !!isOpen);
            });

            scope.$on('$destroy', function () {
                element.unbind('click', toggleDropdown);
            });
        }
    };

【问题讨论】:

  • 你需要JS来激活鼠标悬停功能
  • 好吧,我可以使用 js,但我不想添加我在查看 popover 时看到的几百行以及随之而来的所有内容。我希望是否有某种方法可以修改下拉指令。
  • 或许你想试试bootstrap的tooltip功能
  • 我查看了工具提示,但我们正在寻找与下拉菜单匹配的内容以保持相同。这就是为什么我对下拉列表的任何潜在小修改非常感兴趣,这可以帮助我和其他任何寻找相同内容的人。我查过,但在网上找不到任何示例。
  • @Alan 你能把 JS 小提琴放在一起吗?我们可以调查一下。

标签: angularjs angular-ui-bootstrap


【解决方案1】:

这只需要一点额外的 CSS 即可完成。您没有在问题中提供您的标记,所以我只是使用文档中的按钮组示例。如果您提供特定标记,我会相应地调整此答案。

@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css";


.btn-group:hover>.dropdown-menu {
  display: block;
}
<!doctype html>
<html ng-app="ui.bootstrap.demo">

<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>


</head>

<body>

  <div ng-controller="DropdownCtrl">

    <!-- Single button -->
    <div class="btn-group" dropdown is-open="status.isopen">
      <button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled">
        Button dropdown <span class="caret"></span>
      </button>
      <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>
    </div>

    <!-- Split button -->
    <div class="btn-group" dropdown>
      <button type="button" class="btn btn-danger">Action</button>
      <button type="button" class="btn btn-danger dropdown-toggle" dropdown-toggle>
        <span class="caret"></span>
        <span class="sr-only">Split button!</span>
      </button>
      <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>
    </div>

  </div>
  <script>
    angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
    angular.module('ui.bootstrap.demo').controller('DropdownCtrl', function($scope, $log) {
      $scope.items = [
        'The first choice!',
        'And another choice for you.',
        'but wait! A third!'
      ];

      $scope.status = {
        isopen: false
      };

      $scope.toggled = function(open) {
        $log.log('Dropdown is now: ', open);
      };

      $scope.toggleDropdown = function($event) {
        $event.preventDefault();
        $event.stopPropagation();
        $scope.status.isopen = !$scope.status.isopen;
      };
    });
  </script>
</body>

</html>

实际上,下拉列表所做的只是在单击父元素时将open 类添加到父元素。 Bootstrap CSS 包含一个规则,该规则会导致具有 .dropdown-menu 类的子元素将其显示属性设置为阻止:

.open>.dropdown-menu {
  display: block;
}

因此,要在悬停时显示菜单,可以使用 CSS 中的 :hover 伪类来执行相同的操作。在此示例中,我将规则附加到 .btn-group 父元素,如下所示:

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

【讨论】:

  • 这看起来正是我所需要的。我会试试这个,如果可以,我会接受答案。感谢您的帮助。
  • 这在 PC 上运行良好。但是,当我在 iPad 中打开页面时,悬停下拉菜单变为常规单击下拉菜单(这很好,因为 iPad 上没有悬停),但问题是选择菜单后下拉菜单不会消失。要关闭它,您必须触摸其他接受输入的地方。有什么解决方法吗?
  • @miliu,我倾向于这样做的方式是使用函数将折叠变量设置为折叠状态并将其放在每个下拉元素的 ng-click 中。如果您有一些其他功能已经在 ng-click 上,您可以单独传递它,例如:ng-click="doSomething(); collapseMenu()"。如果它没有意义,请发布一个问题,我会回答或其他人会 - PS 抱歉之前删除的评论,我只是在回答一个类似的问题并将两者混淆了。
  • 有时在将光标移动到列表时列表会关闭。
【解决方案2】:

这是我的简单但低保真解决方案。将 Mouseover 和 mouseleave 放在顶级列表项上是我最大的 Eureka,因此它们作用于组:

 <li uib-dropdown is-open="status.isopen" ng-mouseover="status.isopen = true" ng-mouseleave="status.isopen = false">
                <a ui-sref="abc">ABC</a>
                <ul uib-dropdown-menu role="menu">
                    <li role="menuitem"><a ui-sref="def">DEF</a></li>
                </ul>
            </li>

【讨论】:

  • 这是最简单的实现方式!
【解决方案3】:

你可以装饰指令。

通过这种方式,您不必接触原始代码,并且可以保持原始行为。

HTML

<a href="#" class="open-dropdown-on-hover" dropdown-toggle></a>

JS

angular.module('app').config(uiDropdownToggleDecorate);

uiDropdownToggleDecorate.$inject = ['$provide'];

function uiDropdownToggleDecorate($provide) {
    // the trick here is you have to put 'Directive' after the original directive name
    $provide.decorator('dropdownToggleDirective', uiDropdownToggleDecorator);

    uiDropdownToggleDecorator.$inject = ['$delegate'];

    function uiDropdownToggleDecorator($delegate) {

        var directive = $delegate[0];
        var link = directive.link;

        directive.compile = function() {
            return function(scope, elem, attrs, ctrl) {
                link.apply(this, [scope, elem, attrs, ctrl]);

                function toggle() {
                    if (elem.hasClass('open-dropdown-on-hover')) {
                        scope.$apply(function() {
                            ctrl.toggle();
                        });
                    }
                }

                elem.hover(function() {
                    toggle();
                }, function() {
                    toggle();
                });
            };
        };

        return $delegate;
    }
}

【讨论】:

  • 该指令在较新版本中称为 uibDropdownToggleDirective。对我来说,当我尝试选择列表中的一个项目时,菜单会关闭。
【解决方案4】:

只需在is-open中添加一个范围变量,然后添加属性ng-mouseover="status.isopen = true"

<div class="btn-group" uib-dropdown ng-mouseover="status.isopen = true" is-open="status.isopen">

或者,您可以使用 ng-mouseenter="status.isopen = true" 和 ng-mouseleave="status.isopen = false" 但是这有时会导致下拉菜单在您进入向下状态时关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2017-12-15
    相关资源
    最近更新 更多