ASP.NET MVC:Masterpage:如何在活动菜单项上设置css类

时间:2009-06-03 14:40:44

标签: javascript asp.net-mvc

我的主页上有以下菜单:

<ul id="menu" class="lavaLampBottomStyle">
    <li>
        <%= Html.ActionLink("Employees", "Index", "Employees")%></li>
    <li>
        <%= Html.ActionLink("Customer", "Details", "Account")%></li>
</ul>

我需要一种方法将当前活动li的css类设置为“current”。

我首先猜测是在javascript的帮助下做到这一点。

我会在主页中包含这样的内容:

  $("#menu li a").each(){
    if($(this).attr("href") == '<%= *GET CURRENT PAGE* %>'){
       $(this).parent("li").addClass("current");
    }
  }

这是一个好方法吗?

如果是,我如何获得当前的URL部分,如在href?

如果不是,你的建议是什么? : - )

仅供参考,我之后生成的html:

<ul id="menu" class="lavaLampBottomStyle">
    <li>
        <a href="/KszEmployees/Index">Employees</a></li>
    <li>
        <a class="current" href="/">Customer</a></li>
</ul>

5 个答案:

答案 0 :(得分:15)

如果你想在服务器端做这件事,我之前已经做过了。创建操作过滤器属性:

public class PageOptionsAttribute : ActionFilterAttribute
{
    public string Title { get; set; }
    public string Section { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.Controller as ControllerBase;
        if (controller != null)
        {
            controller.SetPageSection(this.Section);
            controller.SetPageTitle(this.Title);
        }

        base.OnActionExecuting(filterContext);
    }
}

这会在我的ControllerBase类中调用我的所有控制器继承的两个方法:

public class ControllerBase : Controller
{
    public void SetPageSection(string section)
    {
                    // use the section defined or the controller name if none
        ViewData["PageSection"] = section != null ? 
                        section : this.RouteData.Values["controller"].ToString();
    }

    public void SetPageTitle(string title)
    {
        ViewData["PageTitle"] = title;
    }
}

在控制器方法上设置标题和页面部分:

public class HomeController : ControllerBase
{
    [PageOptions(Title="Home Page", Section="Home")]
    public ActionResult Index()
    { }
 }

然后我从我的母版页调用ViewData值(这不会干扰ViewData.Model):

<body class="<%=ViewData["PageSection"] %>">

然后通过CSS引用,而不是调用.current,给每个导航项目一个ID,然后将body类与该ID结合使用来确定当前页面。

body.home #HomeNav { /* selected */  }
body.about #AboutNav { /* selected */  }

答案 1 :(得分:9)

从window.location中提取当前位置。然后使用一个指定href属性值的选择器来选择那些匹配的元素(可能只有一个)。

 var currentLocation = window.location.href;
 // probably needs to be massaged to extract just the path so that it works in dev/prod

$("#menu li a[href$="+currentLocation+"]").addClass("current");

答案 2 :(得分:6)

这可能是最不强化的方式。如果您可以指望用户启用了javascript,我认为这没有任何问题,并且偶尔也会自己完成。

Request.Url是您感兴趣的对象,用于获取服务器端的当前页面。 tvanfosson使用window.location.href的建议也不错,如果你想把它完全留在客户端。

使用serverside的优点是,Request.Url具有易于访问的URL部分,例如Request.Url.Host等,以帮助满足您的链接需求。

答案 3 :(得分:0)

我遇到了同样的问题。使用以下答案,我设法将下面的解决方案放在一起。

https://stackoverflow.com/a/4733394/280972

https://stackoverflow.com/a/5650735/280972

在HtmlHelpers.cs中:

public static class HtmlHelpers
{
    public static HtmlString MenuLink(
        this HtmlHelper htmlHelper,
        string linkText,
        string actionName,
        string controllerName
    )
    {
        var currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        var currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
        var link = htmlHelper.ActionLink(linkText, actionName, controllerName);
        var prefix = (actionName == currentAction && controllerName == currentController) ? String.Format("<li class=\"current\">") : String.Format("<li>");
        const string suffix = "</li>";
        return new HtmlString(prefix + link + suffix);
    }
}

在布局中:

<ul class="nav nav-list">
    <li class="nav-header">Statistics</li>
    @Html.MenuLink("Number of logins", "Logins", "Statistics")
</ul>

请注意,MenuLink-helper会同时创建li-tag和a-tag。

非常欢迎对此解决方案的反馈!

答案 4 :(得分:-2)

这不应该用Javascript完成!确定您所在的页面是服务器端代码的作用,它不是UI行为。

将菜单作为用户控件并将值传递给它以指示应突出显示菜单的哪个部分。我是前端人员,而不是.NET开发人员,但是这样:

<yourControl:menuControl runat="server" ID="menu" selectedPage="4" />