Angular Bootstrap Закрыть открытую панель навигации при нажатии снаружи (как раскрывающийся список)

Я использую Angular Bootstrap в своем приложении. Я использую 2 панели навигации в этом. он работает правильно для меня и отзывчив тоже. Что я хочу сделать, так это сделать кнопку переключения навигации в виде раскрывающегося списка вместо того, чтобы приходить и оставаться там.

Вот что я пробовал http://plnkr.co/edit/CMxdQnSWCiDmOt9NWngJ?p=preview

Я создал директиву

app.directive('navDropdown', function ($parse, $document) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            var fn = $parse(attr.navDropdown);
            $document.bind('click', clickOutsideHandler);
            element.bind('remove', function () {
                $document.unbind('click', clickOutsideHandler);
            });
            function clickOutsideHandler(event) {
                var clickover = $(event.target);
                var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
                if (_opened === true && !clickover.hasClass("navbar-toggle")) {
                    // $("button.navbar-toggle").click();
                    $(".navbar .navbar-collapse").removeClass("in");
                    scope.navCollapsed = false;
                }
            }
        }
    };
});

И я использовал директиву в обоих элементах nav. Но это не работает должным образом.

В первый раз может работать нормально. Но если вы щелкнете снаружи, а затем попытаетесь открыть меню, вам нужно будет дважды нажать кнопку. Иногда это тоже не работает.

Как я могу это решить?

Мне нужно закрыть все навигационные и выпадающие меню, когда мы нажимаем снаружи. Если мы щелкнем внутри любой навигации, закроем все, кроме текущего.

Спасибо.


person Shiju K Babu    schedule 10.07.2015    source источник


Ответы (1)


Для вашей проблемы с щелчком у меня есть эта хорошая директива:

  app.directive('offClick', ['$document', '$timeout', function ($document, $timeout) {

     function targetInFilter(target, filter) {
        if (!target || !filter) return false;
        var elms = angular.element(document.querySelectorAll(filter));
        var elmsLen = elms.length;
        for (var i = 0; i < elmsLen; ++i)
           if (elms[i].contains(target)) return true;
        return false;
     }

     return {
        restrict: 'A',
        scope: {
           offClick: '&',
           offClickIf: '&'
        },
        link: function (scope, elm, attr) {

           if (attr.offClickIf) {
              scope.$watch(scope.offClickIf, function (newVal, oldVal) {
                 if (newVal && !oldVal) {
                    $timeout(function () {
                       $document.on('click', handler);
                    });
                 } else if (!newVal) {
                    $document.off('click', handler);
                 }
              }
              );
           } else {
              $document.on('click', handler);
           }

           scope.$on('$destroy', function () {
              $document.off('click', handler);
           });

           function handler(event) {
              // This filters out artificial click events. Example: If you hit enter on a form to submit it, an
              // artificial click event gets triggered on the form's submit button.
              if (event.pageX == 0 && event.pageY == 0) return;

              var target = event.target || event.srcElement;
              if (!(elm[0].contains(target) || targetInFilter(target, attr.offClickFilter))) {
                 scope.$apply(scope.offClick());
              }
           }
        }
     };
  }]);

на вашем html вы можете использовать так:

<div id="dvTravelers" ng-click="clickMenuTravelers()" off-click="clickMenuTravelers()" off-click-filter="#dvAddTravelersModal" off-click-if="menuVarOpen">

затем вы можете установить свою логику внутри функций в событии клика внутри и снаружи

person Lucas Roselli    schedule 10.07.2015