如何让Twitter-Bootstrap导航栏显示活动链接?

108

我不太理解 Twitter Bootstrap 是如何为导航栏设置活动链接的。如果我的导航栏是这样的(使用 Ruby on Rails 进行链接):

<ul class="nav">
  <li class="active"> <a href="/link">Link</a> </li>
  <li class=""> <a href="/link">Link</a> </li>
  <li class=""> <a href="/link">Link</a> </li>        
</ul>

如何根据所点击的链接保持其处于活动状态?


1
FYI:我使用active_link_to gem并指定 {:wrap_class => :li}。 当 REQUEST_URI 匹配 HREF 值时,这将创建:<li class='active'>...</li>... - Justin E
23个回答

175
你可以使用类似以下的代码(与 @phil 提到的非常相似,但更加简短):
<ul class="nav">
  <li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>
  <li class="<%= 'active' if current_page?(about_path) %>"><%= link_to "About", about_path %></li>
  <li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to "Contact", contact_path %></li>
</ul>

10
如果网站有子导航,该方法就无法奏效。路径会改变,但你仍处于同一部分。明白了吗? - Jakob Dam Jensen
3
可以的,如果你想要突出显示菜单项,无论在控制器中使用什么方法,你可以使用@Pierre的解决方案:'active' if params[:controller] == 'controller1' - yorch
是的,那是最优雅的方法!谢谢 :) - squiter
2
我该如何添加更多路径或特定路径,例如 user_*_path<%= 'active' if current_page?(root_path) %> 中? - Ismoh
1
您如何添加多个路径以使菜单项处于活动状态?例如,如果下拉菜单中有几个组件属于同一菜单项,并且您希望在下拉菜单中找到任何页面时都将菜单项设置为活动状态,该怎么办?请尽快告诉我们。 - msc

98

我在这里刚刚为同一个问题做出了答案 Twitter Bootstrap Pills with Rails 3.2.2

<ul class="nav">
  <li class="<%= 'active' if params[:controller] == 'controller1' %>"> <a href="/link">Link</a> </li>
  <li class="<%= 'active' if params[:controller] == 'controller2' %>"> <a href="/link">Link</a> </li>
  <li class="<%= 'active' if params[:controller] == 'controller3' %>"> <a href="/link">Link</a> </li>        
</ul>

22
我认为这里的想法是正确的,但直接访问params哈希表似乎不是一个好主意。同样的,重复相同的代码也不是好的做法。我建议至少使用current_page?方法来检查当前的控制器/操作,并且还应该将代码移动到一个帮助程序中,以避免代码重复。 - Dustin Frazier
2
我想知道如何用Haml编写相同的内容。将其转换为Haml对我来说行不通。或者我可能在某个地方错了。 - benchwarmer
14
HAML 实现 %li{:class => "#{'active' if current_page?(root_path)}"}=link_to "Home", root_path - Brian
有没有一种优雅的方法,可以在不进行数据库请求的情况下,使用friendly_id gem使其正常工作? - Engin Erdogan
6
Rails文档推荐使用controller_nameaction_name帮助方法来获取控制器名和动作名,而不是从参数哈希中访问它们。 - Alexander Suraphel
对于HAML还可以这样写:%li{class: params[:controller].nil? ? 'active' : ''}= link_to 'Home', root_path - Al17

47

7
喜欢它。为什么要重复造轮子? - lightyrs
这确实是正确的方法...除非您不想引入另一个依赖项。 - Mark G.

34
我将使用助手函数,以Rails表单助手的风格来实现此功能。
在一个助手函数中(例如:app/helpers/ApplicationHelper.rb):
def nav_bar
  content_tag(:ul, class: "nav navbar-nav") do
    yield
  end
end

def nav_link(text, path)
  options = current_page?(path) ? { class: "active" } : {}
  content_tag(:li, options) do
    link_to text, path
  end
end

然后,在视图中(例如app/views/layouts/application.html.erb):
<%= nav_bar do %>
  <%= nav_link 'Home', root_path %>
  <%= nav_link 'Posts', posts_path %>
  <%= nav_link 'Users', users_path %>
<% end %>

这个例子会在“用户”页面上产生以下结果:

<ul class="nav navbar-nav">
  <li><a href="/">Home</a></li>
  <li><a href="/posts">Posts</a></li>
  <li class="active"><a href="/users">Users</a></li>
</ul>

太棒了!谢谢! - Krzysztof Witczak
我喜欢这个想法,不过我会给nav_link函数添加第三个参数,叫做html={},然后将其传递给link_to。这样,你就可以像通常使用link_to一样,向nav_link传递一个html哈希。 - Ryan Friedman

22

使用此代码可在没有服务器代码的情况下基于当前路由选择导航中的活动链接:

    $(document).ready(function () {
        $('a[href="' + this.location.pathname + '"]').parent().addClass('active');
    });

2
这是最佳解决方案,因为它也适用于下拉菜单,并且我包含了以下代码行 $('li.active').closest('.dropdown').addClass('active'); 来突出显示父菜单。 - Seralto
如何更改以适用于子页面?例如,http://example.com/home 将起作用。 我需要在 http://example.com/home/page 的情况下,链接“Home”也处于活动状态。 - athultuttu

11

我在使用 haml 中的 逻辑与 (&&) 方式时取得了成功:

%ul.nav
  %li{class: current_page?(events_path) && 'active'}
    = link_to "Events", events_path
  %li{class: current_page?(about_path) && 'active'}
    = link_to "About Us", about_path

5
每个链接:
<% if current_page?(home_path) -%><li class="active"><% else -%><li><% end -%>
  <%= link_to 'Home', home_path %>
</li>

甚至可以
<li <% if current_page?(home_path) -%>class="active"<% end -%>>
  <%= link_to 'Home', home_path %>
</li>

3

基础,不使用辅助工具

<%= content_tag(:li, class: ('active' if request.path == '/contact')) do %>
    <%= link_to 'Contact', '/contact' %>
<% end %>

由于我有多个类,所以我使用这个 -

<%= content_tag(:li, class: (request.path == '/contact' ? 'active black' : 'black')) do %>
    <%= link_to 'Contact', '/contact' %>
<% end %>

1
这对于任何子导航也适用...只需在子链接中使用父请求路径即可。 - scottkekoa

3

不确定您是在询问如何使用 Twitter Bootstrap CSS 还是 Rails 方面的问题。我假设您是关于 Rails 方面的问题。

如果是这样,请查看 #link_to_if 方法或 #link_to_unless_current 方法。


3

今天我有同样的问题/问题,但采用了另一种解决方法。 我在application_helper.rb中创建了一个辅助函数:

def navMainAktiv(actionName)
    if params[:action] == actionName    
    "active"
    end
end

链接长这样:

<li class="<%= navMainAktiv('about')%>"><%= link_to "About", about_path %></li>

您可以将params[:action]替换为params[:controller],并在链接中设置控制器名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接