2011-01-18 40 views
64

Tôi đã quét xung quanh để tìm một giải pháp thích hợp để gán lớp "hiện hoạt/hiện tại" cho các mục menu từ trang chính. Dòng này được chia nhỏ giữa liên quan đến việc có nên thực hiện điều này với máy khách và phía máy chủ không.mục menu đang hoạt động - trang chủ asp.net mvc3

Thật sự tôi mới dùng cả JavaScript và MVC nên tôi không có ý kiến. Tôi thích làm điều này theo cách "sạch nhất" và thích hợp nhất.

Tôi có mã jQuery sau để gán lớp "hoạt động" cho mục <li> ... vấn đề duy nhất là mục "chỉ mục" hoặc mục menu xem mặc định sẽ luôn được chỉ định lớp đang hoạt động, vì URL luôn là chuỗi con của các liên kết menu khác:

(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 
    } 
}); 

Có cách nào tốt hơn để làm điều này không? Có ai đó ít nhất sẽ giúp tôi có được phiên bản chống đạn phía máy khách? Vì vậy, "chỉ mục" hoặc liên kết mặc định luôn "hoạt động"? Có cách nào để gán một phần mở rộng giả cho phương pháp chỉ mục không? thay vì chỉ là URL cơ sở, nó sẽ là localhost/home/dashboard để nó không phải là chuỗi con của mọi liên kết?

Thật sự, tôi không thực sự làm theo các phương pháp làm điều này phía máy chủ, đó là lý do tại sao tôi đang cố gắng để làm điều đó phía khách hàng với jQuery ... bất kỳ trợ giúp sẽ được đánh giá cao.

Trả lời

114

Một helper HTML tùy chỉnh thường không được công việc tốt:

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); 
} 

và trong trang chủ của bạn:

<ul> 
    <li>@Html.MenuLink("Link 1", "link1", "Home")</li> 
    <li>@Html.MenuLink("Link 2", "link2", "Home")</li> 
</ul> 

Bây giờ tất cả những gì còn lại là xác định lớp CSS hiện tại.

+27

Đáng chú ý htmlHelper.ActionLink() cần "using System.Web.Mvc.Html;" – 4imble

+1

Hoạt động rực rỡ +1 – 4imble

+5

Bạn cũng cần phải nhập không gian tên trong chế độ xem của mình, nếu sử dụng Dao cạo trong MVC3, bạn có thể thực hiện việc này bằng cách thêm @using vào chế độ xem của bạn – Duncan

-1

Điều tôi thường làm là gán một lớp vào thẻ nội dung dựa trên phần đường dẫn. Vì vậy, như thế, nếu bạn làm một String.Replace trên đường dẫn để biến/blog/posts/1 to class = "blogs posts 1".

Sau đó, bạn có thể gán quy tắc CSS để xử lý điều đó. Ví dụ, nếu bạn có một mục trình đơn cho "blog", bạn có thể chỉ cần làm một quy tắc như

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

hoặc nếu bạn muốn có một phong cách đặc biệt nếu bạn trên một bài đăng chỉ phó nếu bạn đang ở trên vào thư mục gốc trên blog trang

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

không phát điên lên vì giải pháp này đòi hỏi ... tạo ra một lớp cho mỗi mục menu đơn, phải không? – Michael

4

Đây là giải pháp của tôi về vấn đề này.

Tôi tạo ra theo phương pháp mở rộng của lớp 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"; 
    } 

Sau đó, tôi có menublock tôi. Có vẻ như sau:

<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> 

Vì vậy, phương thức của tôi trả về tên lớp cho mỗi div theo hành động hiện tại của Bộ điều khiển chính. Bạn có thể đi sâu hơn và thêm vào phương thức một tham số, trong đó chỉ định tên của bộ điều khiển để tránh các vấn đề, khi bạn có các hành động có cùng tên nhưng với các bộ điều khiển khác nhau.

5

gia tăng hỗ trợ cho các lĩnh vực:

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()); 
    } 
} 
2

Qua JQuery u có thể làm như thế này:

$(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; 
} 

gốc: http://www.paulund.co.uk/use-jquery-to-highlight-active-menu-item

Các vấn đề liên quan