新手问题 一般 shared view 中的 nav,如何给当前页面的 li 加上 class='active'?

zisasign · 2013年11月18日 · 最后由 camel 回复于 2013年11月23日 · 8640 次阅读

http://ruby-china.org/topics/15604 这篇看到其中提到 nav 的 active class 的写法,才想起自己对这点一直有些疑惑。

自己一般是这么写:

li class=(controller_name == 'articles' ? 'active' : nil)

靠 controller_name 或是 action_name 来判别当前页面的 controller 或 action,在对应的 li 上添加 active。

要是更复杂的情况,比如有 namespace,可能还要用到 controller_path。

貌似没什么问题,但一直不太清楚这么写好不好,还有没有更好的写法?

跑去翻 ruby-china 的代码,看到是用了 render_list,可没找到这个方法的定义,这是某个 gem 提供的么?

不复杂的话,我会移到前端去做.. 参照一下这个:https://github.com/jhough10/Centurion/blob/master/js/centurion.js#L18

@saiga 这也是个方法哈,没想到过,谢谢。

其实也就不外乎两种方法:

1、你提到的:通过页面逻辑控制; 2、#saiga 提到的前端控制;

ruby-china 使用的是bootstrap-helper

@w7938940 @046569 果然是有 gem 的。

@shatle 恩,不知道会不会有性能上的差别。

@zisasign

第一种,就要重新渲染整个页面,才看到变化;页面不容易出错,简单。

第二种,有多个方法: 1、页面不刷新,只更新主体内容,nav 使用 js 操作状态; 这方法需要自己掌控好页面结构,比如 pjax。

2、页面整个刷新,但把 nav 的状态从页面(如.erb)传给 js,然后由 js 根据状态值进行操作; 其实,我觉得和第一种方法一样,甚至还不如第一种;

3、如果 nav 的多个内容,是同时加载,那么就用 js 控制,没必要重新刷新页面。

暂时想到就这些了。建议使用第一种,前期没必要把页面搞复杂;爱折腾的另算!

LS 的好复杂.. 我的方法是用 JS 拿到 nav 下面所有的链接,移除 active,然后跟当前浏览器地址匹配,对得上的就给它加上 active。当然,这有很大的局限。不过省了很多 if else。另外,可以扩展到级联菜单上

试试current_page?

以前也用过 LZ 这种土办法。。。

#saiga 确实是好方法,通过 js 利用地址判断,因为通常 rails 中的 url 路径是分 controller 的

#11 楼 @hooopo 我觉得基于 URL 来高亮的思路过于理想化,复杂一点的业务系统里面经常出现两个完全不同的 URL 要高亮同一个链接

我觉得换个思路想会简单很多,页面上某个链接是否要高亮,属于页面展示逻辑,那么就应当将这块逻辑写到对应的 view 里面,比如 nav 上这么写

<li class="<%= 'active' if curr_nav == "A" %>">aaa</li>
<li class="<%= 'active' if curr_nav == "B" %>">bbb</li>

而在页面针对相应的变量赋值就行

<% curr_nav = 'A' %>

当然这些代码用 helper 封装一下用起来会更简单

#15 楼 @edokeh 你仔细看一下,应该包含了你说的这种情况。

#16 楼 @hooopo 看到的, Proc.new{ request.path == "/"} 这样的方式写起来很麻烦 所以我的思路是不根据 URL 来高亮,而是由 view 模板自身控制

#17 楼 @edokeh 这种是特殊情况,大多数是按一般规则来高亮。

额 几天没来回复了这么多…… 谢谢各位的建议。

#8 楼 @saiga 曾经也是这样做,但 JS 一般要等页面 render ready 才做,用户会感觉延迟。server 端做会好一些。

我在 view 里是

render_nav 'name1'
render_nav 'name2'
render_nav 'name3'

render 整个 nav list。

然后在 controller 里配置当前要 active 的 nav。

controller 里

current_nav 'name1'

对所有 action 生效。

action 里

current_nav 'name2'

只应用当前 action。

render_navcurrent_nav分别为 helper 和 concern,需要自己实现。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号