Как я могу изменить ui.bootstrap.dropdown, чтобы ответить на наведение мыши над кнопкой "Отмена"?

Я хотел бы использовать окно сообщения ui.bootstrap.dropdown, чтобы отображать текстовую информацию (а не ссылки) аналогично ui.bootstrap.popover. Я хотел бы изменить эту директиву, так как она составляет 99% от того, что мне нужно, и я не хочу добавлять все дополнительные JS, которые требуется для popover.

Другими словами, я бы хотел, чтобы "область раскрывающегося списка" отображалась, когда пользователь наводил курсор мыши на стрелку вниз, а затем уходил, когда они отталкивают мышь от стрелки вниз.

Есть ли способ добавить параметр 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);
            });
        }
    };

Ответы

Ответ 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>

Ответ 2

Здесь мое простое, но lo-fi решение. Наличие 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;
    }
}

Ответ 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", однако иногда это может привести к тому, что вы опуститесь вниз, когда вы переходите вниз.