活动菜单项 - asp.net mvc3 母版页

Posted

技术标签:

【中文标题】活动菜单项 - asp.net mvc3 母版页【英文标题】:active menu item - asp.net mvc3 master page 【发布时间】:2011-06-11 08:32:51 【问题描述】:

我一直在四处寻找合适的解决方案,将“活动/当前”类分配给母版页中的菜单项。关于是否做这个客户端和服务器端,这条线被分成了中间。

说实话,我对 javascript 和 MVC 都是新手,所以我没有意见。我更愿意以“最干净”和最合适的方式来做这件事。

我有以下 jQuery 代码将“活动”类分配给

项...唯一的问题是“索引”或默认视图菜单项将始终被分配活动类,因为 URL 是总是其他菜单链接的子字符串:
(default) index = localhost/
link 1 = localhost/home/link1
link 2 = localhost/home/link1

$(function () 
 var str = location.href.toLowerCase();
  $('#nav ul li a').each(function() 
   if (str.indexOf(this.href.toLowerCase()) > -1) 
    $(this).parent().attr("class","active"); //hightlight parent tab
   
);

有没有更好的方法呢,伙计们?至少有人会帮我获得客户端版本的防弹吗?这样“索引”或默认链接始终是“活动的”?有没有办法给索引方法分配一个假扩展?不是只是基本 URL 而是 localhost/home/dashboard 这样它就不会是每个链接的子字符串?

说实话,我并没有真正遵循做这个服务器端的方法,这就是为什么我试图用 jQuery 做它的客户端......任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

通过 JQuery 你可以这样做:

$(document).ready(function () 
    highlightActiveMenuItem();
);

highlightActiveMenuItem = function () 
    var url = window.location.pathname;
    $('.menu a[href="' + url + '"]').addClass('active_menu_item');
;

.active_menu_item 
    color: #000 !important;
    font-weight: bold !important;

原文:http://www.paulund.co.uk/use-jquery-to-highlight-active-menu-item

【讨论】:

【参考方案2】:

增加了对区域的支持:

public static class MenuExtensions

    public static MvchtmlString MenuItem(this HtmlHelper htmlHelper, string text, string action, string controller, string area = null)
    

        var li = new TagBuilder("li");
        var routeData = htmlHelper.ViewContext.RouteData;

        var currentAction = routeData.GetRequiredString("action");
        var currentController = routeData.GetRequiredString("controller");
        var currentArea = routeData.DataTokens["area"] as string;

        if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(currentArea, area, StringComparison.OrdinalIgnoreCase))
        
            li.AddCssClass("active");
        
        li.InnerHtml = htmlHelper.ActionLink(text, action, controller, new area, null).ToHtmlString();
        return MvcHtmlString.Create(li.ToString());
    

【讨论】:

【参考方案3】:

这是我对这个问题的解决方案。

我创建了以下 HtmlHelpers 类的扩展方法:

public static class HtmlHelpers

    public static string SetMenuItemClass(this HtmlHelper helper, string actionName)
    
        if (actionName == helper.ViewContext.RouteData.Values["action"].ToString())
            return "menu_on";
        else
            return "menu_off";
    

然后我有我的菜单块。它看起来像这样:

<div id="MenuBlock">
    <div class="@Html.SetMenuItemClass("About")">
        <a>@Html.ActionLink("About", "About", "Home")</a></div>
    <img   class="line"  src="@Url.Content("~/Content/theme/images/menu_line.gif")"/>
    <div class="@Html.SetMenuItemClass("Prices")">
        <a>@Html.ActionLink("Prices", "Prices", "Home")</a></div>
</div>

所以我的方法根据 Home 控制器的当前操作将类名返回给每个 div。 您可以更深入地向方法中添加一个参数,该参数指定控制器的名称以避免出现问题,当您有同名但不同控制器的操作时。

【讨论】:

【参考方案4】:

我通常做的是为基于路径部分的主体标签分配一个类。就像,如果您在路径上执行 String.Replace 以将 /blogs/posts/1 变为 class="blogs posts 1"。

然后,您可以分配 CSS 规则来处理它。例如,如果您有一个“博客”菜单项,您可以执行类似

的规则
BODY.blogs li.blogs  /* your style */

或者如果你想要一个特定的风格,如果你在一个帖子上,如果你在博客根页面上,那么你只是副手

BODY.blogs.posts li.blogs /* your style */

【讨论】:

这个解决方案并不疯狂...需要为每个菜单项创建一个类,不是吗?【参考方案5】:

自定义 HTML 助手通常可以很好地完成这项工作:

public static MvcHtmlString MenuLink(
    this HtmlHelper htmlHelper, 
    string linkText, 
    string actionName, 
    string controllerName
)

    string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
    string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
    if (actionName == currentAction && controllerName == currentController)
    
        return htmlHelper.ActionLink(
            linkText,
            actionName,
            controllerName,
            null,
            new 
                @class = "current"
            );
    
    return htmlHelper.ActionLink(linkText, actionName, controllerName);

在您的母版页中:

<ul>
    <li>@Html.MenuLink("Link 1", "link1", "Home")</li>
    <li>@Html.MenuLink("Link 2", "link2", "Home")</li>
</ul> 

现在剩下的就是定义 .current CSS 类了。

【讨论】:

值得注意的是 htmlHelper.ActionLink() 需要“使用 System.Web.Mvc.Html;” 您还需要在视图中导入命名空间,如果在 MVC3 中使用 Razor,您只需将 @using 添加到视图中即可完成此操作 我有一个问题。如果在“link2”页面中我有一个指向“link3”的链接,该链接指向另一个控制器和操作,但它是“link2”部分的一部分。 “link2”不再作为控制器处于活动状态,并且请求中的操作与我们传递给帮助程序的内容不匹配。我制定了一个干净的解决方案:没有会话,视图中没有丑陋的代码。 arturito.net/2011/08/03/… 额外的部分是一个带有路由映射的字典。 结合答案,这也很有用:msdn.microsoft.com/en-us/… @gardarvalur,您可以从 RouteData 中检索它们,就像使用任何其他参数一样:RouteData.Value["foobar"]

以上是关于活动菜单项 - asp.net mvc3 母版页的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net Mvc 突出显示当前页面链接技术?

asp.net mvc子页面怎么调用母版页的js事件

ASP.NET MVC之路由特性以及母版页呈现方式

如何使用动态母版页为每个用户制作自定义菜单?

asp.net 中母版页、用户控件中属性的调用、赋值方法求解。

ASP.NET内容页中访问母版页中的对象