如何突出显示当前菜单项?

And*_*yuk 202 angularjs

AngularJS是否以任何方式帮助在active当前页面的链接上设置类?

我想有一些神奇的方法,但我似乎无法找到.

我的菜单看起来像:

 <ul>
   <li><a class="active" href="/tasks">Tasks</a>
   <li><a href="/actions">Tasks</a>
 </ul>
Run Code Online (Sandbox Code Playgroud)

我在路线上为每个人配备了控制器:TasksControllerActionsController.

但我无法想出一种方法来绑定a控制器链接上的"活动"类.

任何提示?

Ren*_*des 262

在视图上

<a ng-class="getClass('/tasks')" href="/tasks">Tasks</a>
Run Code Online (Sandbox Code Playgroud)

在控制器上

$scope.getClass = function (path) {
  return ($location.path().substr(0, path.length) === path) ? 'active' : '';
}
Run Code Online (Sandbox Code Playgroud)

有了这个,任务链接将在任何以'/ tasks'开头的url中具有活动类(例如'/ tasks/1/reports')

  • 我更喜欢符号`ngClass ="{active:isActive('/ tasks')}`,其中`isActive()`将返回一个布尔值,因为它解耦控制器和标记/样式. (113认同)
  • 如果有人想知道如果路径是"/"则不会加倍的代码,这就是它(抱歉格式化):$ scope.getClass = function(path){if($ location.path(). substr(0,path.length)== path){if(path =="/"&& $ location.path()=="/"){return"active"; } else if(path =="/"){return""; } return"active"} else {return""}} (6认同)
  • 这将最终匹配"/"和"/任何"或如果你有多个菜单项与类似的网址,如"/ test","/ test/this","/ test/this/path"如果你在/ test,它会突出显示所有这些选项. (4认同)
  • 我把它更改为if($ location.path()== path),y path是"/ blah"等 (3认同)

kfi*_*fis 86

我建议在链接上使用指令.

但它还不完美.注意hashbangs;)

这是javascript for指令:

angular.module('link', []).
  directive('activeLink', ['$location', function (location) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs, controller) {
        var clazz = attrs.activeLink;
        var path = attrs.href;
        path = path.substring(1); //hack because path does not return including hashbang
        scope.location = location;
        scope.$watch('location.path()', function (newPath) {
          if (path === newPath) {
            element.addClass(clazz);
          } else {
            element.removeClass(clazz);
          }
        });
      }
    };
  }]);
Run Code Online (Sandbox Code Playgroud)

以下是如何在html中使用它:

<div ng-app="link">
  <a href="#/one" active-link="active">One</a>
  <a href="#/two" active-link="active">One</a>
  <a href="#" active-link="active">home</a>
</div>
Run Code Online (Sandbox Code Playgroud)

之后使用css设计样式:

.active { color: red; }
Run Code Online (Sandbox Code Playgroud)

  • 如果你试图使用Bootstrap并且需要根据li中h的href的哈希进行设置,那么使用`var path = $(element).children("a")[0] .hash.substring(1) ;`.这适用于像`<li active-link ="active"> <a href="#/dashboard"> Dashboard </a> </ li>这样的风格. (7认同)
  • 我会更改`scope.$ watch('location.path()',function(newPath){`for` scope.$ on('$ locationChangeStart',function(){`. (2认同)
  • 如果您正在使用ng-href,只需更改:`var path = attrs.href;`到`var path = attrs.href || attrs.ngHref;` (2认同)

End*_*050 47

这是一个适用于Angular的简单方法.

<ul>
    <li ng-class="{ active: isActive('/View1') }"><a href="#/View1">View 1</a></li>
    <li ng-class="{ active: isActive('/View2') }"><a href="#/View2">View 2</a></li>
    <li ng-class="{ active: isActive('/View3') }"><a href="#/View3">View 3</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在AngularJS控制器中:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};
Run Code Online (Sandbox Code Playgroud)

该主题还有许多其他类似的答案.

如何使用Angular JS设置bootstrap navbar活动类?


Pyl*_*nux 32

只是为了在辩论中添加我的两分钱,我已经制作了一个纯角度模块(没有jQuery),它也可以使用包含数据的哈希网址.(例如#/this/is/path?this=is&some=data)

您只需将模块添加为依赖项并添加auto-active到菜单的其中一个祖先.像这样:

<ul auto-active>
    <li><a href="#/">main</a></li>
    <li><a href="#/first">first</a></li>
    <li><a href="#/second">second</a></li>
    <li><a href="#/third">third</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

模块看起来像这样:

(function () {
    angular.module('autoActive', [])
        .directive('autoActive', ['$location', function ($location) {
        return {
            restrict: 'A',
            scope: false,
            link: function (scope, element) {
                function setActive() {
                    var path = $location.path();
                    if (path) {
                        angular.forEach(element.find('li'), function (li) {
                            var anchor = li.querySelector('a');
                            if (anchor.href.match('#' + path + '(?=\\?|$)')) {
                                angular.element(li).addClass('active');
                            } else {
                                angular.element(li).removeClass('active');
                            }
                        });
                    }
                }

                setActive();

                scope.$on('$locationChangeSuccess', setActive);
            }
        }
    }]);
}());
Run Code Online (Sandbox Code Playgroud)

(你当然可以使用指令部分)

值得注意的是,这不适用于需要至少或只需要的空哈希(例如example.com/#或仅仅example.com).但是这会随着ngResource等自动发生.example.com/#/example.com#/

这里是小提琴:http://jsfiddle.net/gy2an/8/

  • 如果其他人有任何好主意,我现在已经为拉取请求创建了一个Github仓库:https://github.com/Karl-Gustav/autoActive (2认同)

小智 22

在我的情况下,我通过创建一个负责导航的简单控制器解决了这个问题

angular.module('DemoApp')
  .controller('NavigationCtrl', ['$scope', '$location', function ($scope, $location) {
    $scope.isCurrentPath = function (path) {
      return $location.path() == path;
    };
  }]);
Run Code Online (Sandbox Code Playgroud)

只需将ng-class添加到元素中就像这样:

<ul class="nav" ng-controller="NavigationCtrl">
  <li ng-class="{ active: isCurrentPath('/') }"><a href="#/">Home</a></li>
  <li ng-class="{ active: isCurrentPath('/about') }"><a href="#/about">About</a></li>
  <li ng-class="{ active: isCurrentPath('/contact') }"><a href="#/contact">Contact</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)


小智 14

对于AngularUI路由器用户:

<a ui-sref-active="active" ui-sref="app">
Run Code Online (Sandbox Code Playgroud)

这将active在所选对象上放置一个类.

  • 这是一个ui-router指令,如果你使用内置路由器,也就是ngRoute它不起作用.也就是说,ui-router很棒. (2认同)

Tos*_*osh 13

有一个ng-class指令,它绑定变量和css类.它还接受对象(className vs bool值对).

这是一个例子,http://plnkr.co/edit/SWZAqj

  • 这是更新的plnkr:http://plnkr.co/edit/JI5DtK(满足猜测的要求),只显示替代解决方案. (3认同)

hol*_*hix 13

来自@ Renan-tomal-fernandes 的答案很好,但需要一些改进才能正常工作.实际上,它总是会检测到主页(/)的链接被触发,即使你在另一个部分.

所以我稍微改进了一下,这是代码.我使用Bootstrap,因此活动部分在<li>元素而不是<a>.

调节器

$scope.getClass = function(path) {
    var cur_path = $location.path().substr(0, path.length);
    if (cur_path == path) {
        if($location.path().substr(0).length > 1 && path.length == 1 )
            return "";
        else
            return "active";
    } else {
        return "";
    }
}
Run Code Online (Sandbox Code Playgroud)

模板

<div class="nav-collapse collapse">
  <ul class="nav">
    <li ng-class="getClass('/')"><a href="#/">Home</a></li>
    <li ng-class="getClass('/contents/')"><a href="#/contests/">Contents</a></li>
    <li ng-class="getClass('/data/')"><a href="#/data/">Your data</a></li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)


cor*_*rin 10

在阅读了上面的一些优秀建议后,我想出了解决方案.在我的特殊情况下,我试图使用Bootstrap选项卡组件作为我的菜单,但不想使用Angular-UI版本,因为我希望选项卡充当菜单,其中每个选项卡都是可书签的,而不是选项卡充当单个页面的导航.(如果您对Angular-UI版本的引导选项卡的外观感兴趣,请参阅http://angular-ui.github.io/bootstrap/#/tabs).

我真的很喜欢kfis关于创建自己的指令来处理这个问题的答案,但是有一个指令需要放在每个链接上似乎很麻烦.所以我创建了自己的Angular指令,该指令被放置在ul.为了防止其他任何人试图做同样的事情,我想我会在这里发布,但正如我所说,许多上述解决方案也可以.就JavaScript而言,这是一个稍微复杂的解决方案,但它创建了一个具有最小标记的可重用组件.

以下是指令的javascript和路由提供程序ng:view:

var app = angular.module('plunker', ['ui.bootstrap']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/One', {templateUrl: 'one.html'}).
        when('/Two', {templateUrl: 'two.html'}).
        when('/Three', {templateUrl: 'three.html'}).
        otherwise({redirectTo: '/One'});
  }]).
  directive('navTabs', ['$location', function(location) {
    return {
        restrict: 'A',
        link: function(scope, element) {
            var $ul = $(element);
            $ul.addClass("nav nav-tabs");

            var $tabs = $ul.children();
            var tabMap = {};
            $tabs.each(function() {
              var $li = $(this);
              //Substring 1 to remove the # at the beginning (because location.path() below does not return the #)
              tabMap[$li.find('a').attr('href').substring(1)] = $li;
            });

            scope.location = location;
            scope.$watch('location.path()', function(newPath) {
                $tabs.removeClass("active");
                tabMap[newPath].addClass("active");
            });
        }

    };

 }]);
Run Code Online (Sandbox Code Playgroud)

然后在你的HTML中,你只需:

<ul nav-tabs>
  <li><a href="#/One">One</a></li>
  <li><a href="#/Two">Two</a></li>
  <li><a href="#/Three">Three</a></li>
</ul>
<ng:view><!-- Content will appear here --></ng:view>
Run Code Online (Sandbox Code Playgroud)

以下是它的内容:http://plnkr.co/edit/xwGtGqrT7kWoCKnGDHYN?p = preview .


小智 9

你可以非常简单地实现这个,这是一个例子:

<div ng-controller="MenuCtrl">
  <ul class="menu">
    <li ng-class="menuClass('home')"><a href="#home">Page1</a></li>
    <li ng-class="menuClass('about')"><a href="#about">Page2</a></li>
  </ul>

</div>
Run Code Online (Sandbox Code Playgroud)

你的控制器应该是这样的:

app.controller("MenuCtrl", function($scope, $location) {
  $scope.menuClass = function(page) {
    var current = $location.path().substring(1);
    return page === current ? "active" : "";
  };
});
Run Code Online (Sandbox Code Playgroud)


小智 5

使用angular-ui-router的ui-sref-active指令 https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statename

<ul>
  <li ui-sref-active="active" class="item">
    <a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
  </li>
  <!-- ... -->
</ul>
Run Code Online (Sandbox Code Playgroud)


Jea*_*yle 5

在 Bootstrap 4.1 中使用 Angular 版本 6

我能够像下面看到的那样完成它。

在下面的示例中,当 URL 看到“/contact”时,引导程序将被添加到 html 标记中。当 URL 更改时,它将被删除。

<ul>
<li class="nav-item" routerLink="/contact" routerLinkActive="active">
    <a class="nav-link" href="/contact">Contact</a>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

当链接的路由变为活动时,此指令允许您将 CSS 类添加到元素。

Angular 网站上阅读更多内容