带Bootstrap Navbar的MVC - 将所选项设置为活动状态

时间:2014-03-14 14:09:32

标签: asp.net-mvc twitter-bootstrap twitter-bootstrap-3

我正在学习Bootstrap并且无法将所选项目放入" active"州。活动状态保留在默认项目上。新选择/单击的项目会短暂更改为活动状态,但会恢复原状。我已阅读了所有帖子,仍无法使此代码正常运行。我正在使用MVC5和JQuery 2.1。

修改 如果我将li的href更改为 href ="#" ,则会正确应用活动类。加载新视图时会发生什么?我认为塞巴斯蒂安的回应很接近,但对于区域来说却很混乱。

标记

<div class="navbar-wrapper">
    <div class="container">
        <div class="navbar navbar-inverse navbar-fixed-top">

            <div class="navbar-header">
                <a class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </a>
                <a class="navbar-brand" href="#">Test</a>
            </div>
            <div class="btn-group pull-right">
                <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
                    <i class="icon-user"></i>Login
          <span class="caret"></span>
                </a>
                <ul class="dropdown-menu">
                    <li><a href="#">Profile</a></li>
                    <li class="divider"></li>
                    <li><a href="#">Sign Out</a></li>
                </ul>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="~/Home">Home</a></li>
                    <li><a href="~/Home/About">About</a></li>
                    <li><a href="~/Student">Students Sample</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
                        <ul class="dropdown-menu">
                            <li><a href="~/Admin/Home/Index"">Admin</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>
                            <li><a href="#">One more separated link</a></li>
                        </ul>
                    </li>
                </ul>
            </div>

        </div>
    </div>
    <!-- /container -->
</div>
<!-- /navbar wrapper -->

脚本

<script type="text/javascript">

    $(function () {
        $('.navbar-nav li').click(function () {
            $(this).addClass('active').siblings().removeClass('active');
        });
    });

</script>

编辑: 以下是我在发布的答案和一些研究的帮助下最终做的事情。

public static string MakeActive(this UrlHelper urlHelper,string action, string controller, string area = "")
        {
            string result = "active";
            string requestContextRoute;
            string passedInRoute;

            // Get the route values from the request           
            var sb = new StringBuilder().Append(urlHelper.RequestContext.RouteData.DataTokens["area"]);
            sb.Append("/");
            sb.Append(urlHelper.RequestContext.RouteData.Values["controller"].ToString());
            sb.Append("/");
            sb.Append(urlHelper.RequestContext.RouteData.Values["action"].ToString());
            requestContextRoute = sb.ToString();

            if (string.IsNullOrWhiteSpace(area))
            {
                passedInRoute = "/" + controller + "/" + action;
            }
            else
            {
                passedInRoute = area + "/" + controller + "/" + action;
            }

            //  Are the 2 routes the same?
            if (!requestContextRoute.Equals(passedInRoute, StringComparison.OrdinalIgnoreCase))
            {
                result = null;
            }

            return result;
        }

7 个答案:

答案 0 :(得分:28)

您必须根据当前网址检入您的控制器或查看哪个菜单项处于活动状态:

我有一个类似于此的扩展方法:

public static string MakeActiveClass(this UrlHelper urlHelper, string controller)
{
    string result = "active";

    string controllerName = urlHelper.RequestContext.RouteData.Values["controller"].ToString();

    if (!controllerName.Equals(controller, StringComparison.OrdinalIgnoreCase))
    {
        result = null;
    }

    return result;
}

您可以在视图中使用它:

<!-- Make the list item active when the current controller is equal to "blog" -->
<li class="@Url.MakeActive("blog")">
   <a href="@Url.Action("index", "blog")">....</a>
</li>

答案 1 :(得分:19)

JavaScript无法运行,因为页面在运行后会重新加载。因此,它正确设置活动项,然后加载页面,因为浏览器正在关注链接。就个人而言,我会删除你拥有的JavaScript,因为它没有用处。要执行此客户端(而不是您拥有的服务器端代码),您需要JavaScript来在新页面加载时设置活动项。就像是:

$(document).ready(function() {
    $('ul.nav.navbar-nav').find('a[href="' + location.pathname + '"]')
        .closest('li').addClass('active');
});

我建议您在导航栏中添加ID或其他类,以确保选择了正确的类。

答案 2 :(得分:6)

最简单的方法是从控制器发送ViewBag参数,如下所示;

public ActionResult About()
    {            
        ViewBag.Current = "About";
        return View();
    }


    public ActionResult Contact()
    {            
        ViewBag.Current = "Contact";
        return View();
    }

在cshtml页面中执行以下操作;

           <ul class="nav navbar-nav">                    
                <li class="@(ViewBag.Current == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
                <li class="@(ViewBag.Current == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>

here

中的@Damith提供

答案 3 :(得分:6)

只需在任何视图中执行此操作

<ul class="nav navbar-nav">
    @Html.NavigationLink("Link1", "Index", "Home")
    @Html.NavigationLink("Link2", "Index", "Home")
    @Html.NavigationLink("Link3", "Index", "Home")
    @Html.NavigationLink("Links with Parameter", "myAction", "MyController", new{ id=999}, new { @class= " icon-next" })
</ul>

将此方法添加到新类或现有HtmlExtensions类

之后
public static class HtmlExtensions
{
    public static MvcHtmlString NavigationLink(this HtmlHelper html, string linkText, string action, string controller, object routeValues=null, object css=null)
    {
        TagBuilder aTag = new TagBuilder("a");
        TagBuilder liTag = new TagBuilder("li");
        var htmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(css);
        string url = (routeValues == null)?
            (new UrlHelper(html.ViewContext.RequestContext)).Action(action, controller)
            :(new UrlHelper(html.ViewContext.RequestContext)).Action(action, controller, routeValues);

        aTag.MergeAttribute("href", url);
        aTag.InnerHtml = linkText;
        aTag.MergeAttributes(htmlAttributes);

        if (action.ToLower() == html.ViewContext.RouteData.Values["action"].ToString().ToLower() && controller.ToLower() == html.ViewContext.RouteData.Values["controller"].ToString().ToLower())
            liTag.MergeAttribute("class","active");

        liTag.InnerHtml = aTag.ToString(TagRenderMode.Normal);
        return new MvcHtmlString(liTag.ToString(TagRenderMode.Normal));
    }
}

答案 4 :(得分:2)

我相信你有向后的选择。您正在添加该类,然后将其从兄弟姐妹中删除,我认为执行删除操作会导致问题。你可以尝试将其改为:

<script type="text/javascript">

    $(function () {
        $('.navbar-nav li').click(function () {
            $(this).siblings().removeClass('active');
            $(this).addClass('active');
        });
    });

</script>

答案 5 :(得分:0)

您的javascript函数应该可以正常运行...问题是您的链接路由到控制器并重新加载整个页面。为了避免这种行为,您可以将您的身体内容渲染为局部视图,这样导航栏元素就不会重新加载。你不应该编写一个函数来处理dom事件 - 这就是javascript的用途。

要了解我的意思,请更改您的代码:

<li><a href="~/Home/About">About</a></li>
<li><a href="~/Student">Students Sample</a></li>

为:

 <li><a href="">About</a></li>
 <li><a href="">Students Sample</a></li>

答案 6 :(得分:0)

只需添加此JQuery编码:

<script>
        $(document).ready(function () {
            $('body').find('a[href="' + location.pathname + '"]')
                .addClass('active');
        });
</script>