активный пункт меню - главная страница asp.net mvc3 - PullRequest
65 голосов
/ 18 января 2011

Я сканировал, пытаясь найти подходящее решение для назначения класса «активный / текущий» пунктам меню на главной странице.Строка разделена посередине относительно того, делать ли этот клиент против серверной стороны.

По правде говоря, я новичок в JavaScript и MVC, поэтому у меня нет мнения.Я бы предпочел сделать это «самым чистым» и наиболее подходящим способом.

У меня есть следующий код jQuery, чтобы назначить «активный» класс элементу

... единственная проблема - это "index "или элементу меню вида по умолчанию всегда будет назначаться активный класс, потому что 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
   }
});

Есть ли лучший способ сделать это, ребята?Может ли кто-нибудь хотя бы помочь мне получить пуленепробиваемую версию на стороне клиента?Чтобы ссылка «индекс» или ссылка по умолчанию всегда была «активной»?Есть ли способ присвоения фальшивого расширения методу index?например, вместо базового URL-адреса он будет localhost/home/dashboard, чтобы он не был подстрокой каждой ссылки?

По правде говоря, я действительно не следую методам выполнения этой серверной части, котораяВот почему я пытаюсь сделать это на стороне клиента с jQuery ... любая помощь будет оценена.

Ответы [ 5 ]

114 голосов
/ 19 января 2011

Пользовательский помощник 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> 

Теперь осталось только определить класс CSS .current.

5 голосов
/ 16 мая 2012

Добавлена ​​поддержка областей:

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());
    }
}
4 голосов
/ 09 марта 2011

Вот мое решение этой проблемы.

Я создал следующий метод расширения класса 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";
    }

Тогда у меня есть свой menublock.Это выглядит так:

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

Так что мой метод возвращает имя класса каждому div в соответствии с текущим действием контроллера Home.Вы можете пойти глубже и добавить в метод один параметр, который указывает имя контроллера, чтобы избежать проблем, когда у вас есть действия с тем же именем, но с разными контроллерами.

2 голосов
/ 15 сентября 2013

Через 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

0 голосов
/ 18 января 2011

Что я обычно делаю, так это назначаю класс тегу body, основанный на частях пути. Например, если вы сделаете String.Replace на пути, чтобы включить / blogs / posts / 1 в class = "blogs posts 1".

Затем вы можете назначить правила CSS для обработки этого. Например, если у вас есть пункт меню для «блогов», вы можете просто сделать правило вроде

BODY.blogs li.blogs { /* your style */}

или если вы хотите определенный стиль, если вы используете только пост, если вы находитесь на корневой странице блога

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