マスターページのメニュー項目に「アクティブ/現在」のクラスを割り当てるための適切な解決策を見つけようとして、私はスキャンしました。このクライアント対サーバー側を実行するかどうかに関して、行は中央で分割されます。
正直なところ、私はJavaScriptとMVCの両方が初めてなので、意見はありません。 「最もクリーンな」最も適切な方法でこれを行うことを望みます。
URLが常にサブストリングであるため、「アクティブ」クラスを<li>アイテムに割り当てる次のjQueryコードがあります...唯一の問題は「インデックス」またはデフォルトの表示メニューアイテムが常にアクティブクラスに割り当てられることです他のメニューリンク:
(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を使用してクライアント側で実行しようとしています。
通常、カスタム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クラスを定義するだけです。
エリアのサポートを追加しました:
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());
}
}
この問題の私の解決策は次のとおりです。
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 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>
したがって、私のメソッドは、Homeコントローラーの現在のアクションに従って、すべてのdivにクラス名を返します。同じ名前で異なるコントローラーのアクションがある場合、問題を回避するためにコントローラーの名前を指定する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