简体   繁体   English

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

[英]ASP.NET MVC: Masterpage: How to set css class on active menu item

I have the following menu in my masterpage: 我的主页中有以下菜单:

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

I need a way to set the css class of the current active li to "current". 我需要一种方法将当前活动li的css类设置为“current”。

My first guess it to do this with the assistance of javascript. 我的第一个猜测是在javascript的帮助下做到这一点。

I would include something like this in the masterpage: 我会在主页中包含这样的内容:

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

Is this a good approach? 这是一个好方法吗?

If it is, how can I get the current URL part like in the href? 如果是,我如何获得当前的URL部分,如在href中?

If it isn't, what's your suggestion? 如果不是,你的建议是什么? :-) :-)

FYI, the generated html I'm after: 仅供参考,我之后生成的html:

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

If you want to do it all server-side, I've done this before. 如果你想在服务器端做这一切,我之前就已经这样做了。 Create an action filter attribute: 创建操作过滤器属性:

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

This calls two methods in my ControllerBase class that all my controllers inherit from: 这会在我的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;
    }
}

Set the title and page section on you controller methods: 在控制器方法上设置标题和页面部分:

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

Then I call the ViewData value from my master page (this won't interfere with ViewData.Model): 然后我从我的母版页调用ViewData值(这不会干扰ViewData.Model):

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

Then to reference via CSS, instead of calling .current, give each nav item an ID and then use the body class in combination with that ID to determine the current page. 然后通过CSS引用,而不是调用.current,给每个导航项一个ID,然后使用body类结合该ID来确定当前页面。

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

Extract the current location from window.location. 从window.location中提取当前位置。 Then use a selector that specifies the value of the href attribute to choose just those elements that match (presumably only one). 然后使用指定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");

That's probably the least intensive way of doing it. 这可能是最不强化的方式。 If you can count on the users to have javascript enabled, I see nothing wrong with this, and have done it myself on occasion. 如果您可以指望用户启用了javascript,我认为这没有任何问题,并且有时我自己完成了。

Request.Url is the object you are interested in to get the current page on the server side. Request.Url是您感兴趣的对象,用于获取服务器端的当前页面。 The suggestion to use window.location.href by tvanfosson isn't bad either if you want to keep it entirely clientside. tvanfosson使用window.location.href的建议也不错,如果你想把它完全留在客户端。

The advantage of using serverside, is that Request.Url has easily accessible parts of the url, such as Request.Url.Host, etc to help with your link-munging needs. 使用serverside的优点是,Request.Url具有易于访问的URL部分,例如Request.Url.Host等,以帮助满足链接修改需求。

I had the same problem. 我有同样的问题。 Using the following answers, I managed to put together the solution below. 使用以下答案,我设法将下面的解决方案放在一起。

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

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

In HtmlHelpers.cs: 在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);
    }
}

In the layout: 在布局中:

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

Note that the MenuLink-helper creates both the li-tag and the a-tag. 请注意,MenuLink-helper会同时创建li-tag和a-tag。

Feedback on this solution is very welcome! 非常欢迎对此解决方案的反馈!

This should NOT be done with Javascript! 这不应该用Javascript完成! Deciding which page you are on is the job of the server side code, it's not a UI behaviour. 确定您所在的页面是服务器端代码的工作,它不是UI行为。

Have the menu as a user control and pass a value to it to indicate which part of the menu should be highlighted. 将菜单作为用户控件并将值传递给它以指示应突出显示菜单的哪个部分。 I'm front end person, not a .NET developer but something like this: 我是前端人员,而不是.NET开发人员,但是这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM