如何修改ui.bootstrap.dropdown以响应鼠标悬停在拖放按钮上?

时间:2022-11-03 21:36:11

I would like to use the ui.bootstrap.dropdown message box to display text information (not links) in a similar way to the ui.bootstrap.popover. I would like to modify this directive as it does 99% of what I need and I don't want to add all the additional JS that the popover requires.

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

In other words I would like the "dropdown list area" to display when the user hovers the mouse over the down arrow and then go away when they move the mouse away from the down arrow.

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

Is there a way that I could add an option to the ui.bootstrap.dropdown so hovering the mouse over the arrow would show and hide the dropdown box. I don't want to place any links in this box.

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

I hope someone has some ideas that could help me with suggesting how I could change this directive that comes with the 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);
            });
        }
    };

4 个解决方案

#1


37  

This only requires a little extra CSS to accomplish. You didn't provide your markup in the question, so I'm just using the button group examples from the doc. If you provide your specific markup, I'll adjust this answer accordingly.

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

@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>

Really all that the dropdown does is add an open class to the parent element when it is clicked. The Bootstrap CSS contains a rule that causes the child element with the .dropdown-menu class to be have it's display property set to block:

实际上,下拉列表的所有功能是在单击父元素时向其添加一个开放类。 Bootstrap CSS包含一个规则,该规则使具有.dropdown-menu类的子元素将其display属性设置为block:

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

Therefore, to cause the menu to display when you hover, you can use the :hover pseudo class in CSS to do the same. In this example, I attached the rule to the .btn-group parent element as such:

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

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

#2


9  

Here's my simple but lo-fi solution. Having the Mouseover and mouseleave on the top level list item was my biggest Eureka, so they act on the group:

这是我简单但低保真的解决方案。将鼠标悬停和鼠标移动放在*列表项上是我最大的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


6  

You can decorate directives.

你可以装饰指令。

With this way you don't have to touch the original code and you can keep the original behaviour.

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

HTML

HTML

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

JS

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;
    }
}

#4


1  

Just add a scope variable to is-open and then add attribute ng-mouseover="status.isopen = true"

只需将范围变量添加到is-open,然后添加属性ng-mouseover =“status.isopen = true”

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

Alternatively, you can use ng-mouseenter="status.isopen = true" and ng-mouseleave="status.isopen = false" however this can sometimes cause the drop down to close as you move into the down down.

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

#1


37  

This only requires a little extra CSS to accomplish. You didn't provide your markup in the question, so I'm just using the button group examples from the doc. If you provide your specific markup, I'll adjust this answer accordingly.

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

@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>

Really all that the dropdown does is add an open class to the parent element when it is clicked. The Bootstrap CSS contains a rule that causes the child element with the .dropdown-menu class to be have it's display property set to block:

实际上,下拉列表的所有功能是在单击父元素时向其添加一个开放类。 Bootstrap CSS包含一个规则,该规则使具有.dropdown-menu类的子元素将其display属性设置为block:

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

Therefore, to cause the menu to display when you hover, you can use the :hover pseudo class in CSS to do the same. In this example, I attached the rule to the .btn-group parent element as such:

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

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

#2


9  

Here's my simple but lo-fi solution. Having the Mouseover and mouseleave on the top level list item was my biggest Eureka, so they act on the group:

这是我简单但低保真的解决方案。将鼠标悬停和鼠标移动放在*列表项上是我最大的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


6  

You can decorate directives.

你可以装饰指令。

With this way you don't have to touch the original code and you can keep the original behaviour.

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

HTML

HTML

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

JS

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;
    }
}

#4


1  

Just add a scope variable to is-open and then add attribute ng-mouseover="status.isopen = true"

只需将范围变量添加到is-open,然后添加属性ng-mouseover =“status.isopen = true”

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

Alternatively, you can use ng-mouseenter="status.isopen = true" and ng-mouseleave="status.isopen = false" however this can sometimes cause the drop down to close as you move into the down down.

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