[转载]MVC 下导航高亮的完美解决方案 – Dozer .NET 技术博客 – 博客园.
前言
导航高亮一直是一个让大家头疼的问题。
纯 JavaScript 的话可以判断当前页面的地址和链接地址是否有关系。
这样的弊端就是自由度太低,MVC 下会出一定的问题 (MVC 下有默认的 Controller 和 Action)
另一种方案是前端后端结合,为每一张页面设置一个属性,然后在页面中判断。满足条件便高亮。
这样的弊端就是,需要为你所有的页面设置属性,非常麻烦!
那么有没有什么完美的解决方案?一劳永逸的?
神奇的 eval 函数
JavaScript 有精粹也有糟粕,其中的 eval 是大多数动态语言都拥有的精髓。我们是否可以利用这个函数呢?
基本思路:
给每一个 li(对应一个链接)设置一个 class,例如 class=”controller_Home”,
代表着,只要这张页面是的 controller 是 Home,就让这个链接高亮。
而在页面中,是可以通过代码直接得到 controller 和 action 的名称的,没必要为每一张页面单独手动设置。
解决方案
< ul id = "top-navigation" > < li class = "controller_Home" >< span >< span >@Html.ActionLink("首页","Index","Home")</ span ></ span ></ li > < li class = "controller_Article" >< span >< span >@Html.ActionLink("文章管理","Index","Article")</ span ></ span ></ li > < li class = "controller_User" >< span >< span >@Html.ActionLink("用户管理","Index","User")</ span ></ span ></ li > </ ul > < input id = "controller" type = "hidden" value = "@Html.ViewContext.RouteData.Values[" controller"]"/> < input id = "action" type = "hidden" value = "@Html.ViewContext.RouteData.Values[" action"]"/> |
- 首先给所有的 li 加上一个 class
- 然后再利用两个 hidden ,把 controller 和 action 的名字放到前端页面中
$(function () { SetNavClass( 'top-navigation' , 'active' ); }); function SetNavClass(ulId, className) { controller = $( '#controller' ).val(); action = $( '#action' ).val(); eval( 'controller_' + controller + ' = true' ); eval( 'action_' + action + ' = true' ); list = $( '#' + ulId + '>li' ); for ( var k = 0; k < list.length; k++) { item = list[k]; str = GetClassName(item); try { if (eval(str)) $(item).addClass(className); } catch (e) { } } } function GetClassName(item) { classes = $(item).attr( 'class' ).split( ' ' ); for ( var k = 0; k < classes.length; k++) { if (classes[k].indexOf( 'controller' ) > -1 || classes[k].indexOf( 'action' ) > -1) return classes[k]; } } |
以上是 Javascript 的代码:
- 读取 controller 和 action 的名字
- 利用 eval 函数给 controller_[controller名字] 和 action_[action名字] 这两个变量赋值
- 取出 class 中的表达式
- 利用 eval 函数执行表达式,判断最后的结果,如果满足条件就加上高亮的 class
上述代码不需要为每个页面编写,只需要在母版页中编写一次即可,再引用这段 Javascript 函数。
如果你的 ul ID 和 高亮 class 名字不一样,那么只要在调用这个函数的时候传入你自己的就行了。
高级应用
就这么简单?仅此而已?
如果真的是这样,那么完全可以直接利用 Javascript 判断页面地址来实现。
那么让我们来玩一些好玩的吧~
因为是 eval 函数,所以完全可以在这个 class 中编写复杂的表达式(其实就是 Javascript 表达式)
<li class = "controller_Home||controller_About" ><span><span>@Html.ActionLink( "首页" , "Index" , "Home" )</span></span></li> <li class = "controller_Article&&action_Add" ><span><span>@Html.ActionLink( "文章管理" , "Index" , "Article" )</span></span></li> |
以上两行代码表示:
- controller 只要是 Home,或者 About,都会激活这个链接
- controller 必须是 Article,action 必须是 Add
也就是说,在这个 class 里可以输入复杂的 Javascript,这样就可以实现复杂的导航激活功能了!