【问题标题】:How to set bootstrap navbar active class with Angular JS?如何使用 Angular JS 设置引导导航栏活动类?
【发布时间】:2013-04-18 10:37:20
【问题描述】:

如果我在引导程序中有一个带有项目的导航栏

Home | About | Contact

如何在每个菜单项处于活动状态时为其设置活动类?也就是说,当角度路线在

时,如何设置class="active"
  1. #/ 回家
  2. #/about 关于页面
  3. #/contact 联系页面

【问题讨论】:

标签: javascript twitter-bootstrap angularjs angularjs-directive navbar


【解决方案1】:

一种非常优雅的方式是使用 ng-controller 在 ng-view 之外运行单个控制器:

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li>
        <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li>
        <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

并包含在 controllers.js 中:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}

【讨论】:

  • 由于我是新手,如果您能提供一个如何将其放入标头指令的示例,我将不胜感激。
  • 我建议改用return $location.path().indexOf(viewLocation) == 0;,这样您也可以捕获带有参数的页面
  • 这可以完成工作,但几乎没有 elegant - 路由名称,例如 /dogs 必须在调用 isActive('/dogs') 时重复
  • 如果您使用的是 UI Router,那么您可以使用 ui-sref-active/ui-sref-active-eq 指令,即。 ui-sref-active-eq='active'ui-sref-active='active' 达到相同的结果
  • @SvenHecht 这个逻辑的问题是主页链接 (/) 会匹配所有其他路径。
【解决方案2】:

我刚刚写了一个指令来处理这个,所以你可以简单地将属性bs-active-link添加到父元素&lt;ul&gt;,并且任何时候路由改变,它都会找到匹配的链接,并添加active类到对应的&lt;li&gt;

你可以在这里看到它的实际效果:http://jsfiddle.net/8mcedv3b/

示例 HTML:

<ul class="nav navbar-nav" bs-active-link>
  <li><a href="/home">Home</a></li>
  <li><a href="/contact">Contact</a></li>
</ul>

Javascript:

angular.module('appName')
.directive('bsActiveLink', ['$location', function ($location) {
return {
    restrict: 'A', //use as attribute 
    replace: false,
    link: function (scope, elem) {
        //after the route has changed
        scope.$on("$routeChangeSuccess", function () {
            var hrefs = ['/#' + $location.path(),
                         '#' + $location.path(), //html5: false
                         $location.path()]; //html5: true
            angular.forEach(elem.find('a'), function (a) {
                a = angular.element(a);
                if (-1 !== hrefs.indexOf(a.attr('href'))) {
                    a.parent().addClass('active');
                } else {
                    a.parent().removeClass('active');   
                };
            });     
        });
    }
}
}]);

【讨论】:

  • 我比接受的答案更喜欢这个,因为没有配置数据的重复,即路线本身只保留在一个地方,这很有效..
  • 使用 scope.$watch("$routeChangeSuccess", function () { .... 而不是 scope.$on("$routeChangeSuccess", function () {....
  • 为了我自己的目的不得不稍微调整一下,但是很棒的答案!很容易理解。
【解决方案3】:

你可以看看AngularStrap,导航栏指令似乎就是你要找的:

https://github.com/mgcrea/angular-strap/blob/master/src/navbar/navbar.js

.directive('bsNavbar', function($location) {
  'use strict';

  return {
    restrict: 'A',
    link: function postLink(scope, element, attrs, controller) {
      // Watch for the $location
      scope.$watch(function() {
        return $location.path();
      }, function(newValue, oldValue) {

        $('li[data-match-route]', element).each(function(k, li) {
          var $li = angular.element(li),
            // data('match-rout') does not work with dynamic attributes
            pattern = $li.attr('data-match-route'),
            regexp = new RegExp('^' + pattern + '$', ['i']);

          if(regexp.test(newValue)) {
            $li.addClass('active');
          } else {
            $li.removeClass('active');
          }

        });
      });
    }
  };
});

要使用这个指令:

  1. http://mgcrea.github.io/angular-strap/下载AngularStrap

  2. 在 bootstrap.js 之后将脚本包含在您的页面中:
    &lt;script src="lib/angular-strap.js"&gt;&lt;/script&gt;

  3. 将指令添加到您的模块中:
    angular.module('myApp', ['$strap.directives'])

  4. 将指令添加到导航栏:
    &lt;div class="navbar" bs-navbar&gt;

  5. 在每个导航项上添加正则表达式:
    &lt;li data-match-route="/about"&gt;&lt;a href="#/about"&gt;About&lt;/a&gt;&lt;/li&gt;

【讨论】:

  • 谢谢。这帮助我修复了自己的指令(我缺少的洞察力是 scope.$watch
  • 为什么element 变量被传递给jquery 选择器? $('...', element)
  • @Lucio 该方法采用 2 个参数 - jQuery(selector, context) - 第二个参数是传递选择器的上下文,无论是父 DOM 元素还是另一个 jQuery 对象本身 - 阅读更多 here
  • 这对我来说非常有效 - 但是我必须进行一项更改,但根据 mgcrea.github.io/angular-strap 添加到模块的指令是 mgcrea.ngStrap 而不是 $strap.directives
【解决方案4】:

这是一种适用于 Angular 的简单方法。

<ul class="nav navbar-nav">
    <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>

在您的 AngularJS 控制器中:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};

【讨论】:

  • 不错的方法。我稍微修改了一下 - 使用了 ng-class 指令(ng-class={active: isActive('/View1')}) 并更新了 isActive 函数以返回 true/false 而不是类名本身。
  • 我已经像你的例子一样复制了所有内容,对我来说 $location.path() 没有用...切换到 $location.url(),它有效!
【解决方案5】:

如果您使用 Angular 路由器,RouterLinkActive directive 可以非常优雅地使用:

<ul class="navbar-nav">
  <li class="nav-item"><a class="nav-link" routerLink="home" routerLinkActive="active">Home</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="gallery" routerLinkActive="active">Gallery</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="pricing" routerLinkActive="active">Prices</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="contact" routerLinkActive="active">Contact</a></li>
</ul>

【讨论】:

  • 我认为这应该是公认的答案(至少对于 Angular 2+),为什么要实现一些已经实现的东西?但是对于 Bootstrap 3.3,active 类应该在 &lt;li&gt; 中(您可以将 routerLinkActive 与 routerLink 或其父级放在一起)
  • 注意:如果您使用/ 作为您的主页,routerLinkActive 将认为任何以/ 开头的 URL 都处于活动状态,例如/foo//foo/bar 等。要完全匹配,您需要 routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}"
【解决方案6】:

首先,这个问题可以通过多种方式解决。这种方式可能不是最优雅的,但它确实有效。

这是一个简单的解决方案,您应该可以将其添加到任何项目中。当您配置您可以用来关闭的路由时,您可以添加一个“pageKey”或其他一些属性。此外,您可以在 $route 对象的 $routeChangeSuccess 方法上实现一个监听器,以监听路由更改是否成功完成。

当您的处理程序触发时,您会获得页面键,并使用该键来定位需要为此页面“激活”的元素,然后应用 ACTIVE 类。

请记住,您需要一种使所有元素“处于活动状态”的方法。如您所见,我在导航项目上使用 .pageKey 类将它们全部关闭,并且我正在使用 .pageKey_{PAGEKEY} 单独打开它们。将它们全部切换为非活动状态,将被认为是一种幼稚的方法,通过使用先前的路线仅使活动项目处于非活动状态,您可能会获得更好的性能,或者您可以更改 jquery 选择器以仅选择要使其处于非活动状态的活动项目。使用 jquery 选择所有活动项目可能是最好的解决方案,因为它可以确保为当前路由清理所有内容,以防上一个路由上可能存在任何 css 错误。

这意味着更改这行代码:

$(".pagekey").toggleClass("active", false);

到这个

$(".active").toggleClass("active", false);

这里是一些示例代码:

给定一个引导导航栏

<div class="navbar navbar-inverse">
    <div class="navbar-inner">
        <a class="brand" href="#">Title</a>
        <ul class="nav">
            <li><a href="#!/" class="pagekey pagekey_HOME">Home</a></li>
            <li><a href="#!/page1/create" class="pagekey pagekey_CREATE">Page 1 Create</a></li>
            <li><a href="#!/page1/edit/1" class="pagekey pagekey_EDIT">Page 1 Edit</a></li>
            <li><a href="#!/page1/published/1" class="pagekey pagekey_PUBLISH">Page 1 Published</a></li>
        </ul>
    </div>
</div>

还有一个 Angular 模块和控制器,如下所示:

<script type="text/javascript">

    function Ctrl($scope, $http, $routeParams, $location, $route) {

    }



    angular.module('BookingFormBuilder', []).
        config(function ($routeProvider, $locationProvider) {
            $routeProvider.
                when('/', { 
                   template: 'I\'m on the home page', 
                   controller: Ctrl, 
                   pageKey: 'HOME' }).
                when('/page1/create', { 
                   template: 'I\'m on page 1 create', 
                   controller: Ctrl, 
                   pageKey: 'CREATE' }).
                when('/page1/edit/:id', { 
                   template: 'I\'m on page 1 edit {id}', 
                   controller: Ctrl, pageKey: 'EDIT' }).
                when('/page1/published/:id', { 
                   template: 'I\'m on page 1 publish {id}', 
                   controller: Ctrl, pageKey: 'PUBLISH' }).
                otherwise({ redirectTo: '/' });

            $locationProvider.hashPrefix("!");
        }).run(function ($rootScope, $http, $route) {

            $rootScope.$on("$routeChangeSuccess", 
                           function (angularEvent, 
                                     currentRoute,
                                     previousRoute) {

                var pageKey = currentRoute.pageKey;
                $(".pagekey").toggleClass("active", false);
                $(".pagekey_" + pageKey).toggleClass("active", true);
            });

        });

</script>

【讨论】:

  • 您需要向右滚动才能看到路线上的 pageKey 值,这是整个解决方案的关键。
  • 这可能有效,但与 Angular.js 应用程序的一般建议相反:在 Angular 中,您应该避免使用 jQuery 来搞乱 DOM;如果您必须触摸 DOM,请编写指令。
  • 这很完美,如果dom操作困扰你,只需在.navbar上添加一个指令,在routechangesuccess中添加一个$broadcast事件,$rootScope.$broadcast('routeChanged', current.pageKey) ;然后在你的指令上捕获它并在那里进行 dom 操作
【解决方案7】:

你实际上可以使用angular-ui-utils'ui-route指令:

<a ui-route ng-href="/">Home</a>
<a ui-route ng-href="/about">About</a>
<a ui-route ng-href="/contact">Contact</a>

或:

标题控制器

/**
 * Header controller
 */
angular.module('myApp')
  .controller('HeaderCtrl', function ($scope) {
    $scope.menuItems = [
      {
        name: 'Home',
        url:  '/',
        title: 'Go to homepage.'
      },
      {
        name:   'About',
        url:    '/about',
        title:  'Learn about the project.'
      },
      {
        name:   'Contact',
        url:    '/contact',
        title:  'Contact us.'
      }
    ];
  });

索引页

<!-- index.html: -->
<div class="header" ng-controller="HeaderCtrl">
  <ul class="nav navbar-nav navbar-right">
    <li ui-route="{{menuItem.url}}" ng-class="{active: $uiRoute}"
      ng-repeat="menuItem in menuItems">
      <a ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
        {{menuItem.name}}
      </a>
    </li>
  </ul>
</div>

如果您使用 ui-utils,您可能还对 ui-router 感兴趣,用于管理部分/嵌套视图。

【讨论】:

  • ui-route 方法非常诱人,但到目前为止,我还没有设法让它在 Yeoman 的角度生成器生成的项目上工作。
  • @gabuzo:你是通过 bower 安装了 angular-ui-utils 吗?
【解决方案8】:

我觉得所有这些答案对我来说有点过于复杂,抱歉。所以我创建了一个小指令,应该在每个导航栏的基础上工作:

app.directive('activeLink', function () {
    return {
        link: function (scope, element, attrs) {
            element.find('.nav a').on('click', function () {
                angular.element(this)
                    .parent().siblings('.active')
                    .removeClass('active');
                angular.element(this)
                    .parent()
                    .addClass('active');
            });
        }
    };
});

用法:

<ul class="nav navbar-nav navbar-right" active-link>
    <li class="nav active"><a href="home">Home</a></li>
    <li class="nav"><a href="foo">Foo</a></li>
    <li class="nav"><a href="bar">Bar</a></li>
</ul>

【讨论】:

  • 只有在您单击导航栏中的链接后,您的方法才有效。如果您从“Foo”的 URL 开始,最初仍会选择“Home”。例如从 localhost:9000/#/contact 开始会导致主页在导航栏中显示为选中状态。
【解决方案9】:

我使用带有 $location 的 ng-class 指令来实现它。

<ul class="nav">
<li data-ng-class="{active: ($location.path() == '/') }">
    <a href="#/">Carpeta Amarilla</a>
</li>
<li class="dropdown" data-ng-class="{active: ($location.path() == '/auditoria' || $location.path() == '/auditoria/todos') }">
    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
        Auditoria
        <b class="caret"></b>
    </a>
    <ul class="dropdown-menu pull-right">
        <li data-ng-class="{active: ($location.path() == '/auditoria') }">
            <a href="#/auditoria">Por Legajo</a>
        </li>
        <li data-ng-class="{active: ($location.path() == '/auditoria/todos') }">
            <a href="#/auditoria/todos">General</a>
        </li>
    </ul>
</li>
</ul>

它要求导航栏位于主控制器内,可以访问 $location 服务,如下所示:

bajasApp.controller('MenuCntl', ['$scope','$route', '$routeParams', '$location', 
   function MenuCntl($scope, $route, $routeParams, $location) {
   $scope.$route = $route;
   $scope.$location = $location;
   $scope.$routeParams = $routeParams;
}]);

【讨论】:

    【解决方案10】:

    您可以通过角度表达式中的条件来实现这一点,例如:

    <a href="#" class="{{ condition ? 'active' : '' }}">link</a>
    

    话虽如此,我确实发现 angular 指令是更“正确”的方式,即使外包大量此类微型逻辑可能会在某种程度上污染您的代码库。

    我在开发过程中每隔一段时间就使用条件来进行 GUI 样式设置,因为它比创建指令要快一点。我无法告诉你一个实例,尽管它们实际上在代码库中保留了很长时间。最后我要么把它变成指令,要么找到更好的方法来解决问题。

    【讨论】:

      【解决方案11】:

      如果您使用ui-router,则以下示例应根据@DanPantry 对已接受答案的评论满足您的需求,而无需添加任何控制器端代码:

      <div class="collapse navbar-collapse" ng-controller="HeaderController">
          <ul class="nav navbar-nav">
              <li ui-sref-active="active"><a ui-sref="app.home()" href="/">Home</a></li>
              <li ui-sref-active="active"><a ui-sref="app.dogs()" href="/dogs">Dogs</a></li>
              <li ui-sref-active="active"><a ui-sref="app.cats()" href="/cats">Cats</a></li>
          </ul>
      </div>
      <div ng-view></div>
      

      您可以查看docs 了解更多信息。

      【讨论】:

      • 完美!肯定是最干净的解决方案
      • 非常简单的最佳解决方案。谁不使用ui.router
      【解决方案12】:

      如果您不想使用AngularStrap,那么这个指令应该可以解决问题!这是对https://stackoverflow.com/a/16231859/910764的修改。

      JavaScript

      angular.module('myApp').directive('bsNavbar', ['$location', function ($location) {
        return {
          restrict: 'A',
          link: function postLink(scope, element) {
            scope.$watch(function () {
              return $location.path();
            }, function (path) {
              angular.forEach(element.children(), (function (li) {
                var $li = angular.element(li),
                  regex = new RegExp('^' + $li.attr('data-match-route') + '$', 'i'),
                  isActive = regex.test(path);
                $li.toggleClass('active', isActive);
              }));
            });
          }
        };
      }]);
      

      HTML

      <ul class="nav navbar-nav" bs-navbar>
        <li data-match-route="/home"><a href="#/home">Home</a></li>
        <li data-match-route="/about"><a href="#/about">About</a></li>
      </ul>
      

      注意:以上 HTML 类假设您使用的是Bootstrap 3.x

      【讨论】:

        【解决方案13】:

        这是我的看法。在这篇文章中找到了一些答案的组合。我有一个稍微不同的情况,所以我的解决方案包括将菜单分离到它自己的模板中,以便在指令定义对象中使用,然后将我的导航栏添加到我需要它的页面上。基本上,我有一个登录页面,我不想在其中包含我的菜单,所以我使用 ngInclude 并在登录时插入此指令:

        指令:

        module.directive('compModal', function(){
        
        
        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            scope: true,
            templateUrl: 'templates/menu.html',
            controller: function($scope, $element, $location){
                $scope.isActive = function(viewLocation){
        
                    var active = false;
        
                    if(viewLocation === $location.path()){
                        active = true;
                    }
        
                    return active;
        
                }
            }
         }
        });
        

        指令模板(templates/menu.html)

        <ul class="nav navbar-nav">
          <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>
        

        包含指令的 HTML

        <comp-navbar/>
        

        希望对你有帮助

        【讨论】:

        • 函数可以简写为 $scope.isActive = function (viewLocation) { return viewLocation === $location.path(); };
        【解决方案14】:

        扩展 myl 答案,我需要它来处理这样的结构。

        -索引

        -事件 ---事件列表
        ---事件编辑
        ---事件映射

        -地点
        ---地点列表
        ---地方编辑
        ---地点地图

        所以我不得不使用 indexOf,而不是匹配,以验证被格式化以匹配条件的子链接。所以对于“事件”:

        <li ng-class="{ active: isActive('/event')}" class="divider-vertical dropdown">
        
        
        function NavController($scope, $location) { 
        $scope.isActive = function (viewLocation) {
            var s=false;
            if($location.path().indexOf(viewLocation) != -1){
             s = true;
            }
            return s;
        };}
        

        【讨论】:

          【解决方案15】:

          这是一个简单的解决方案

          <ul class="nav navbar-nav navbar-right navbar-default menu">
            <li ng-class="menuIndice == 1 ? 'active':''">
              <a ng-click="menuIndice = 1" href="#/item1">item1</a>
            </li>
            <li ng-class="menuIndice == 2 ? 'active':''">
              <a ng-click="menuIndice = 2" href="#/item2">item2</a>
            </li>
            <li ng-class="menuIndice == 3 ? 'active':''">
              <a ng-click="menuIndice = 3" href="#/item3">item3</a>
            </li>
          </ul>
          

          【讨论】:

            【解决方案16】:

            结合@Olivier 的AngularStrap 答案,我还实现了来自https://github.com/twbs/bootstrap/issues/9013 的kevinknelson 的答案。

            Bootstrap3 导航栏本来就不是为单页(例如 Angular)应用程序设计的,因此在小屏幕上的菜单在单击时不会折叠。

            【讨论】:

              【解决方案17】:

              JavaScript

              /**
               * Main AngularJS Web Application
               */
              
              var app = angular.module('yourWebApp', [
                  'ngRoute'
              ]);
              
              
              /**
               * Setup Main Menu
               */
              
              app.controller('MainNavCtrl', [ '$scope', '$location', function ( $scope, $location) {
                  $scope.menuItems = [
                      {
                          name: 'Home',
                          url:  '/home',
                          title: 'Welcome to our Website'
                      },
                      {
                          name: 'ABOUT',
                          url:  '/about',
                          title: 'Know about our work culture'
                      },
                      {
                          name:   'CONTACT',
                          url:    '/contact',
                          title:  'Get in touch with us'
                      }
                  ];
              
                  $scope.isActive = function (viewLocation) {
                      return viewLocation === $location.path();
                  };
              }]);
              

              HTML

                <div class="navbar-collapse collapse" ng-controller="MainNavCtrl">
                  <ul id="add-magic-line" class="nav navbar-nav navbar-right">
                    <li data-ng-class="{current_page_item: isActive('{{ menuItem.url }}')}" data-ng-repeat="menuItem in menuItems">
                      <a data-ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
                        {{menuItem.name}}
                      </a>
                    </li>
                  </ul>
                </div>
              

              【讨论】:

              • 这不起作用 - 它不会将当前类添加到 DOM
              【解决方案18】:

              感谢@Pylinux。我已经使用了他的技术并对其进行了修改以支持“一级”下拉菜单(sub ul/li),因为这正是我所需要的。在下面的小提琴链接中查看它的实际效果。

              根据 pylinux 的回答更新了 Fiddle - http://jsfiddle.net/abhatia/en4qxw6g/

              为了支持一级下拉菜单,我做了以下三处更改:
              1。为需要有子 ul 列表的 li 下的“a”元素添加了 dd(下拉列表)的类值。

                       <li><a class="dd">This link points to #/fun5</a>
                        <ul>
                          <li><a href="#/fun6?some=data">This link points to #/fun6</a>
                          </li>
                          <li><a href="#/fun7?some=data">This link points to #/fun7</a>
                          </li>
                          <li><a href="#/fun8?some=data">This link points to #/fun8</a>
                          </li>
                          <li><a href="#/fun9?some=data">This link points to #/fun9</a>
                          </li>
                        </ul>
                      </li>
              


              2. 更新 Javascript 以添加以下新逻辑。

               if(angular.element(li).parent().parent().children('a').hasClass("dd"))
               {angular.element(li).parent().parent().children('a.dd').addClass('active');}
              


              3. 更新 CSS 以添加以下内容:

              a.active {background-color:red;}
              

              希望这对希望实现单级下拉菜单的人有所帮助。

              【讨论】:

                【解决方案19】:

                使用对象作为开关变量。
                您可以通过以下方式非常简单地内联:

                <ul class="nav navbar-nav">
                   <li ng-class="{'active':switch.linkOne}" ng-click="switch = {linkOne: true}"><a href="/">Link One</a></li>
                   <li ng-class="{'active':switch.linkTwo}" ng-click="switch = {link-two: true}"><a href="/link-two">Link Two</a></li>
                </ul>
                

                每次单击链接时,开关对象都会被一个新对象替换,其中只有正确的开关对象属性为真。未定义的属性将评估为假,因此依赖于它们的元素将不会分配活动类。

                【讨论】:

                  【解决方案20】:

                  你也可以使用这个主动链接指令https://stackoverflow.com/a/23138152/1387163

                  当位置匹配时,父 li 将获得活动类 /url

                  <li>
                      <a href="#!/url" active-link active-link-parent>
                  </li>
                  

                  【讨论】:

                    【解决方案21】:

                    我建议在链接上使用指令。 Here 是小提琴。

                    但它还不完美。当心hashbangs ;)

                    这是指令的javascript:

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

                    这是它在 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>
                    

                    之后使用 css 进行样式设置:

                    .active{ color:red; }
                    

                    【讨论】:

                      【解决方案22】:

                      只是为了在辩论中增加我的两分钱,我制作了一个纯角度模块(没有 jquery),它也适用于包含数据的哈希 url。 (i.g.#/this/is/path?this=is&amp;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>
                      

                      模块看起来像这样:

                      (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);
                                  }
                              }
                          }]);
                      }());
                      

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

                      ** 还值得注意的是,这不适用于空哈希(i.g.example.com/# 或只是 example.com)它需要至少有 example.com/#/ 或只是 example.com#/。但这会在 ngResource 之类的情况下自动发生。

                      【讨论】:

                      • 这太恶心了。使用 Angular 的原因是为了简单。
                      【解决方案23】:

                      这对我有用:

                        var domain = '{{ DOMAIN }}'; // www.example.com or dev.example.com
                        var domain_index =  window.location.href.indexOf(domain);
                        var long_app_name = window.location.href.slice(domain_index+domain.length+1); 
                        // this turns http://www.example.com/whatever/whatever to whatever/whatever
                        app_name = long_app_name.slice(0, long_app_name.indexOf('/')); 
                        //now you are left off with just the first whatever which is usually your app name
                      

                      然后你使用 jquery(也适用于 angular)来添加类活动

                      $('nav a[href*="' + app_name+'"]').closest('li').addClass('active');
                      

                      当然还有css:

                      .active{background:red;}
                      

                      如果你的 html 是这样的:

                      <ul><li><a href="/ee">ee</a></li><li><a href="/dd">dd</a></li></ul>
                      

                      如果您在 www.somesite.com/ee thaen ee 是“应用程序”并且它将处于活动状态,这将使用页面 url 自动添加活动类并将您的背景颜色为红色

                      【讨论】:

                        【解决方案24】:

                        这个答案很长,但我想我会分享我的方式:

                        .run(function($rootScope, $state){
                         $rootScope.$state = $state;
                        });
                        

                        模板:

                        <ul class="nav navbar-nav">
                            <li ng-class="{ active: $state.contains('View1') }"><a href="...">View 1</a></li>
                            <li ng-class="{ active: $state.contains('View2') }"><a href="...">View 2</a></li>
                            <li ng-class="{ active: $state.contains('View3') }"><a href="...">View 3</a></li>
                        </ul>
                        

                        对于那些使用ui-router的人:

                        <ul class="nav navbar-nav">
                                <li ui-sref-active="active"><a href="...">View 1</a></li>
                                <li ui-sref-active="active"><a href="...">View 2</a></li>
                                <li ui-sref-active="active"><a href="...">View 3</a></li>
                        </ul>
                        

                        对于完全匹配(例如嵌套状态?)使用$state.name === 'full/path/to/state'ui-sref-active-eq="active"

                        【讨论】:

                          【解决方案25】:

                          对于任何可能感兴趣的人来说,这是另一种解决方案。这样做的好处是它具有较少的依赖关系。哎呀,它也可以在没有网络服务器的情况下工作。所以它完全是客户端。

                          HTML:

                          <nav class="navbar navbar-inverse" ng-controller="topNavBarCtrl"">
                          <div class="container-fluid">
                              <div class="navbar-header">
                                  <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-home" aria-hidden="true"></span></a>
                              </div>
                              <ul class="nav navbar-nav">
                                  <li ng-click="selectTab()" ng-class="getTabClass()"><a href="#">Home</a></li>
                                  <li ng-repeat="tab in tabs" ng-click="selectTab(tab)" ng-class="getTabClass(tab)"><a href="#">{{ tab }}</a></li>
                              </ul>
                          </div>
                          

                          解释:

                          在这里,我们使用指令 ng-repeat 从 angularjs 模型动态生成链接。魔术发生在控制器中为下面介绍的此导航栏定义的方法 selectTab()getTabClass()

                          控制器:

                          angular.module("app.NavigationControllersModule", [])
                          
                          // Constant named 'activeTab' holding the value 'active'. We will use this to set the class name of the <li> element that is selected.
                          .constant("activeTab", "active")
                          
                          .controller("topNavBarCtrl", function($scope, activeTab){
                              // Model used for the ng-repeat directive in the template.
                              $scope.tabs = ["Page 1", "Page 2", "Page 3"];
                          
                              var selectedTab = null;
                          
                              // Sets the selectedTab.
                              $scope.selectTab = function(newTab){
                                 selectedTab = newTab;
                              };
                          
                              // Sets class of the selectedTab to 'active'.
                              $scope.getTabClass = function(tab){
                                 return selectedTab == tab ? activeTab : "";
                              };
                          });
                          

                          解释:

                          selectTab() 方法是使用ng-click 指令调用的。所以当点击链接时,变量selectedTab被设置为这个链接的名字。在 HTML 中,您可以看到在没有任何 Home 选项卡参数的情况下调用此方法,以便在页面加载时将其突出显示。

                          getTabClass() 方法通过 HTML 中的 ng-class 指令调用。此方法检查它所在的选项卡是否与selectedTab 变量的值相同。如果为真,则返回“active”,否则返回“”,ng-class 指令将其用作类名。然后,您应用于active 类的任何 CSS 都将应用于选定的选项卡。

                          【讨论】:

                          • 我以任何其他方式导航到另一个选项卡会发生什么?
                          • 什么意思?
                          • 例如页面中的链接将您带到另一个选项卡中的另一个页面。有意义吗?
                          • 在这种情况下,我认为最好使用 Muli Yulzary 在上面回答中建议的 ui-router。 ui-router 为每个 url 分配一个状态。因此,一旦有人单击该链接,用户将被路由到该链接,并且 Angular 应用程序的状态将被更新。然后 ui-sref="active" 将突出显示该选项卡。这是角度 2 的文档:ui-router.github.io/ng2。此外,不要使用普通的引导程序,而是查看用于 Angular 应用程序的 UI Bootstrap。用户界面引导:angular-ui.github.io/bootstrap
                          【解决方案26】:

                          您只需添加所需的active-class 和所需的颜色代码。

                          例如:ng-class="{'active': currentNavSelected}" ng-click="setNav"

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2016-05-27
                            • 1970-01-01
                            • 1970-01-01
                            • 2023-03-20
                            • 2015-12-25
                            • 2017-06-07
                            • 1970-01-01
                            • 2018-01-08
                            相关资源
                            最近更新 更多