4

私は_Layout.cshtmlにこのメニューを持っています:

<td class="MenuStructure">
    <ul id="menu">
        <li>@Html.ActionLink("First Page", "Page1Action", "Main")</li>
        <li>@Html.ActionLink("Second Page", "Page2Action", "Main")</li>
        <li>@Html.ActionLink("Third Page", "Page3Action", "Second")</li>
    </ul>
</td>

アクションリンクの1つがクリックされたときに、それを含む<li>のクラスを「selected」に設定し、他の<li>要素のクラスを「」に設定したいと思います。

これは動作します:

    <script type="text/javascript">
        $(document).ready(function () {
        var selMenu = '@ViewBag.SelectedMenu';
            if (selMenu == "page1") {
                $("#page1").attr('class', 'selected');
                $("#page2").attr('class', '');
                $("#page3").attr('class', '');
            }
            if (selMenu == "page2") {
                $("#page1").attr('class', '');
                $("#page2").attr('class', 'selected');
                $("#page3").attr('class', '');
            }
        });
    </script>

しかし、それはひどく醜いです。誰かが私にこれを行うためのよりエレガントな方法を教えてもらえますか?

4

2 に答える 2

2

要素のグループにクリックイベントハンドラーを追加するaと、クリックされた要素にクラスを簡単に追加して、li兄弟の数に関係なく、すべての兄弟からクラスを削除できます。attrこれにより、ifステートメントと各の更新が不要になりますli

サンプルは次のとおりです。

http://jsfiddle.net/JjBgm/4/

マークアップ:

<ul id="menu">
    <li><a href="#">one</a></li>
    <li><a href="#">two</a></li>
    <li><a href="#">three</a></li>
</ul>

jQuery:

$(document).ready(function() {

    $('#menu li a').click(function() {
        $(this).parent().addClass('selected').siblings().removeClass('selected');
    });

});

MVCを使用して、このアプローチをニーズに合わせて明らかに変更する必要がありますが、この概念は機能するはずです。

編集:関係するサーバーへのラウンドトリップがあるとおっしゃっていたので、上記はうまく機能しない可能性があります。その場合、選択したメニューに基づいてクライアント側IDを作成し、そこからクラスを制御できます。

$(document).ready(function () {
    var selMenu = '@ViewBag.SelectedMenu';
    $("#" + selMenu).addClass('selected').siblings().removeClass('selected');
});

これは、、などがサーバー処理後に結果のマークアップを表示せずに要素を参照することを前提#page1としています。#page2<li>

タグ#page1を参照する場合、ステートメントは次のようになります。<a>

$("#" + selMenu).parent().addClass('selected').siblings().removeClass('selected');

もちろんテストされていません。重要な点は、セレクターを動的に構築し、必要に応じて兄弟セレクターと親セレクターを使用してクラスをクリアすることです。それははるかにきれいです。

于 2012-05-10T17:34:29.927 に答える
0

これがサイトのメインナビゲーションであり、正確なアクションを実行していない場合でもトップメニューを「選択」したままにしておきたいと思います(たとえば、リンクはリストに移動しますが、「編集」に移動します)。ページなど)。

それを行うには2つの方法があります。1つは、ビューバッグにプロパティを配置し、レンダリング時に_layout.cshtmlファイルでそれを確認することです。

// in controller Action method
ViewBag.SelectedMenu = "first"
// in view
<li class="@((ViewBag.SelectedMenu == "first") ? "selected-class" : "")">first link</li>

(私たちが使用する)2番目の方法は、サイトマップパッケージ(NuGetからインストール)を使用することです。次に、ルートでサイトマップファイルを編集し、そこにすべてのリンクを配置します(ナビゲーションに直接使用しないリンクも含む)。次に、コントロールにレンダリング<ul><li>'sしてもらいます。それはあなたが今持っているのと同じhtmlを大部分出力するので、cssはまだ機能するはずです。

  • すべてのメニューを1か所に
  • サイトマップは[承認]属性またはその他のフィルターを尊重し、ログインのみのリンクを非表示にします
  • 実際には存在しない可能性のあるメニューのノードを非表示/表示できます(再マップされたURLなど)
  • 他の素敵な小さな機能がたくさん

Mvc.sitemapファイル:

<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="Get a car" controller="Cars" action="Buy"/>
    <mvcSiteMapNode title="Reports" controller="Report" action="AllReports">
      <mvcSiteMapNode title="" controller="Report" action="ViewMPG"/>
    </mvcSiteMapNode>
</mvcSiteMapNode>

そして、あなたの_Layout.cshtmlファイルで:

<td class="MenuStructure">
    <!-- one level menu starting at top (home), including the "home" link -->
    @Html.MvcSiteMap().Menu(0, true, true, 1)
</td>

次にViews\Shared\MenuHelperModel.cshtml、スタイルを変更するために変更します。

<ul id="menu">
    @foreach (var node in Model.Nodes)
    {
        var show = node.IsInCurrentPath && (!node.IsRootNode || node.IsCurrentNode);
        var cls = show ?  "selected" : ""; 
        <li class="@cls">@Html.DisplayFor(m => node)</li>
    }
</ul>
于 2012-05-10T18:01:13.923 に答える