tag - elemento de menú activo-asp.net mvc3 página maestra
razor vs mvc (5)
A través de JQuery puedes hacer esto:
$(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;
}
Original: http://www.paulund.co.uk/use-jquery-to-highlight-active-menu-item
He estado explorando tratando de encontrar una solución adecuada para asignar clases "activas / actuales" a los elementos del menú de la página maestra. La línea se divide en el medio con respecto a si hacer este lado del cliente vs servidor.
A decir verdad, soy nuevo en JavaScript y MVC, así que no tengo una opinión. Preferiría hacer esto de la manera "más limpia" y más apropiada.
Tengo el siguiente código jQuery para asignar la clase "activa" al elemento <li> ... el único problema es que al elemento de menú "vista previa" o "índice" siempre se le asignará la clase activa, porque la URL siempre es una subcadena de los otros enlaces de menú:
(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
}
});
¿Hay una mejor manera de hacer esto, chicos? Al menos alguien me ayudaría a obtener la versión del cliente a prueba de balas? ¿Para que el "índice" o enlace predeterminado siempre esté "activo"? ¿Hay alguna forma de asignar una extensión falsa al método de índice? como en lugar de solo la URL base, ¿sería localhost/home/dashboard
para que no sea una subcadena de cada enlace?
A decir verdad, realmente no sigo los métodos de hacer este lado del servidor, y es por eso que trato de hacerlo desde el lado del cliente con jQuery ... cualquier ayuda sería apreciada.
Aquí está mi solución de este problema.
Creé el siguiente método de extensión de la clase 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";
}
Entonces tengo mi menublock. Se parece a esto:
<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>
Entonces mi método devuelve el nombre de la clase a cada div según la acción actual del controlador Home. Puede profundizar y agregar al método un parámetro, que especifica el nombre del controlador para evitar problemas, cuando tiene acciones con el mismo nombre pero con diferentes controladores.
Lo que suelo hacer es asignar una clase a la etiqueta corporal que se basa en las partes de la ruta. Entonces, si haces un String, reemplaza la ruta para convertir / blogs / posts / 1 a class = "blogs posts 1".
Luego, puede asignar reglas CSS para manejar eso. Por ejemplo, si tiene un elemento de menú para "blogs", puede hacer una regla como
BODY.blogs li.blogs { /* your style */}
o si quieres un estilo particular si estás en una publicación solo vicio si estás en la página raíz del blog
BODY.blogs.posts li.blogs {/* your style */}
Se agregó soporte para las áreas:
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());
}
}
Un asistente HTML personalizado generalmente hace bien el trabajo:
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);
}
y en tu página maestra:
<ul>
<li>@Html.MenuLink("Link 1", "link1", "Home")</li>
<li>@Html.MenuLink("Link 2", "link2", "Home")</li>
</ul>
Ahora todo lo que queda es definir la clase actual de CSS.