ASP.NET MVC: Masterpage: как установить класс css в активном пункте меню
У меня есть следующее меню на моей главной странице:
<ul id="menu" class="lavaLampBottomStyle">
<li>
<%= Html.ActionLink("Employees", "Index", "Employees")%></li>
<li>
<%= Html.ActionLink("Customer", "Details", "Account")%></li>
</ul>
Мне нужен способ установить класс css текущего активного li в "current".
Сначала я предполагаю, что это делается с помощью javascript.
Я бы включил что-то подобное на главной странице:
$("#menu li a").each(){
if($(this).attr("href") == '<%= *GET CURRENT PAGE* %>'){
$(this).parent("li").addClass("current");
}
}
Это хороший подход?
Если это так, как я могу получить текущую часть URL-адреса, как в href?
Если это не так, то что вы предлагаете?: -)
FYI, сгенерированный html я после:
<ul id="menu" class="lavaLampBottomStyle">
<li>
<a href="/KszEmployees/Index">Employees</a></li>
<li>
<a class="current" href="/">Customer</a></li>
</ul>
Ответы
Ответ 1
Это, вероятно, наименее интенсивный способ сделать это. Если вы можете рассчитывать на то, что у пользователей включен javascript, я не вижу ничего плохого в этом и иногда делал это сам.
Request.Url - это объект, который вас интересует, чтобы получить текущую страницу на стороне сервера. Предложение использовать window.location.href tvanfosson неплохо, если вы хотите сохранить его полностью на стороне клиента.
Преимущество использования serveride заключается в том, что Request.Url имеет легкодоступные части URL-адреса, такие как Request.Url.Host и т.д., чтобы помочь вам в ваших потребностях в ссылках.
Ответ 2
Если вы хотите сделать это на всех серверах, я сделал это раньше. Создайте атрибут фильтра действий:
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, дайте каждому навигационному элементу идентификатор, а затем используйте класс body в сочетании с этим идентификатором, чтобы определить текущую страницу.
body.home #HomeNav { /* selected */ }
body.about #AboutNav { /* selected */ }
Ответ 3
Извлечь текущее местоположение из окна. Затем используйте селектор, который задает значение атрибута 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");
Ответ 4
У меня была та же проблема. Используя следующие ответы, мне удалось собрать решение ниже.
fooobar.com/questions/85990/...
fooobar.com/questions/389256/...
В 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 создает как тег li, так и тег a.
Отзыв об этом решении очень приветствуется!
Ответ 5
Это НЕ должно быть сделано с Javascript! Определение того, на какой странице вы работаете, является заданием кода на стороне сервера, это не поведение пользовательского интерфейса.
Указать меню в качестве пользовательского элемента управления и передать ему значение, чтобы указать, какая часть меню должна быть выделена. Я сторонник, а не разработчик .NET, но что-то вроде этого:
<yourControl:menuControl runat="server" ID="menu" selectedPage="4" />