如何获取Twitter-Bootstrap导航以显示活动链接?


106

我不了解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
仅供参考:我使用active_link_to gem并指定{:wrap_class =>:li}。这会创建:<li class ='active'> ... </ li>,当REQUEST_URI与HREF值匹配时
Justin E

Answers:


95

刚刚在这里对相同的问题做了一个答案 Twitter with Rails 3.2.2的Bootstrap药丸

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

21
我认为这里的想法是正确的,但是直接进入params哈希似乎是个坏主意。同样,一次又一次地重复相同的代码。我建议至少使用current_page?检查当前控制器/动作的方法,并且还将代码移入帮助程序以避免代码重复。
达斯汀·弗雷泽

2
我想知道如何用haml编写相同的内容。转换为haml对我不起作用。也许我在某个地方错了
替补席

14
HAML实施%li{:class => "#{'active' if current_page?(root_path)}"}=link_to "Home", root_path
Brian

有没有一种优雅的方法可以在不执行db请求的情况下使用friendly_id gem进行此项工作?
Engin Erdogan

6
Rails docs建议使用controller_nameand action_name帮助程序,而不是从params哈希访问它们。
Alexander Suraphel 2013年

171

您可以使用类似(类似于@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
如果您有子导航,则无法使用。路径改变了,但是你在同一部分..有意义吗?
雅各布·詹森

3
是的,正确,如果您要突出显示菜单项,而不管您在同一控制器中运行哪种方法,都可以使用@Pierre解决方案:'active' if params[:controller] == 'controller1'
yorch 2013年

是的,这是最优雅的方式!谢谢:)
squiter

2
如何添加更多路径或像user_*_path中的特定路径<%= 'active' if current_page?(root_path) %>
Ismoh 2014年

1
您如何添加多个路径以使菜单项处于活动状态?例如,如果您在下拉菜单中有多个项目是同一菜单项的组成部分,并且想在下拉菜单中找到的任何页面上都使菜单项处于活动状态?请尽快通知我们。
msc 2014年


33

我使用了一个帮助程序,以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。这样,您可以将HTML哈希传递给nav_link,就像通常使用link_to一样。
瑞安·弗里德曼

22

使用它代替当前基于路由的导航中的活动链接,而无需服务器代码:

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

2
这是最好的解决方案,因为它也适用于下拉菜单,并且我还添加了一行$('li.active').closest('.dropdown').addClass('active');以突出显示父菜单。
塞拉尔托

如何更改它也可以申请子页面?就像example.com/home一样。在example.com/home/page的情况下,我还需要激活“主页”链接。
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

今天,我遇到了同样的问题/问题,但是还有其他解决方案。我在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],并在链接设置你的控制器名称。


2

我为每个使用此li

<li><%= link_to_unless_current('Home', root_path) { link_to('Home', root_path, class: 'active') } %></li>


类需求进行设置lia
克里斯托弗Oezbek

2

您可以在中定义一个辅助方法 application_helper.rb

def create_link(text, path)
  class_name = current_page?(path) ? 'active' : ''

  content_tag(:li, class: class_name) do
    link_to text, path
  end
end

现在您可以像这样使用:

create_link 'xyz', any_path 这将呈现为

<li class="active">
  <a href="/any">xyz</a>
</li>

希望能帮助到你!


1

您应该通过操作CSS类来自己做。也就是说,如果用户单击某个链接,然后执行某项操作(目标操作),则将先前的链接设置为非活动状态并将新的链接设置为活动状态。

如果您的链接将您带到服务器(即重新加载页面),那么您只需在服务器上正确呈现活动链接即可。否则,如果您要进行一些客户端操作(切换选项卡窗格或其他操作),则必须使用javascript。



1

current_page?当您可以classhtml_options哈希中指定自定义名称时,我使用内置视图帮助器编写了简单的帮助器方法。

def active_link_to(name = nil, options = nil, html_options = nil, &block)
  active_class = html_options[:active] || "active"
  html_options.delete(:active)
  html_options[:class] = "#{html_options[:class]} #{active_class}" if current_page?(options)
  link_to(name, options, html_options, &block)
end

示例(在root_path旅途中):

<%= active_link_to "Main", root_path %>
# <a href="/" class="active">Main</a>

<%= active_link_to "Main", root_path, class: "bordered" %>
# <a href="/" class="bordered active">Main</a>

<%= active_link_to "Main", root_path, class: "bordered", active: "disabled" %>
# <a href="/" class="bordered disabled">Main</a>

1

这里的许多答案都有一定的用处,或者是部分答案。我结合了很多东西来使我使用这个rails helper方法:

# helper to make bootstrap3 nav-pill <li>'s with links in them, that have
# proper 'active' class if active. 
#
# the current pill will have 'active' tag on the <li>
#
# html_options param will apply to <li>, not <a>. 
#
# can pass block which will be given to `link_to` as normal. 
def bootstrap_pill_link_to(label, link_params, html_options = {})
  current = current_page?(link_params)

  if current
    html_options[:class] ||= ""
    html_options[:class] << " active "
  end

  content_tag(:li, html_options) do
    link_to(label, link_params)
  end      
end

可以通过参数检查使其更加出色,以支持&blocklink_to等。


1

已经有很多答案,但是这是我写的使Bootstrap Icons与活动链接一起工作的内容。希望它会帮助某人

该助手将为您提供:

  1. 具有链接的li元素,其中包含自定义文本
  2. 可选的Bootstrap3图标
  3. 在右侧页面上时将变为活动状态

把它放在你的application_helper.rb

def nav_link(link_text, link_path, icon='')
  class_name = current_page?(link_path) ? 'active' : ''
  icon_class = "glyphicon glyphicon-" + icon

  content_tag(:li, :class => class_name) do
    (class_name == '') ? (link_to content_tag(:span, " "+link_text, class: icon_class), link_path)
    : (link_to content_tag(:span, " "+link_text, class: icon_class), '#')
  end
end

并使用链接:

<%= nav_link 'Home', root_path, 'home'  %>

最后一个参数是可选的-它将图标添加到链接。使用字形图标的名称。如果您想要没有文字的图标:

    <%= nav_link '', root_path, 'home'  %>

1

这是我所做的:

我创建了一个ViewsHelper并包含在ApplicationController中:

include ViewsHelper

在ViewsHelper内部,我创建了一个简单的方法,如下所示:

def page_state(path)
  current_page?(path) ? 'active' : ''
end

我认为我这样做:

<li class="<%= page_state(foobar_path) %>"><%= link_to 'Foobars', foobar_path %></li>

0

听起来您好像需要实现一个导航系统。如果很复杂,它可能会变得很丑陋且很快。

在这种情况下,您可能想要使用可以处理此问题的插件。您可以使用navigasmic简单的导航(我建议使用navigasmic,因为它将主层保留在视图中,它所属的位置,而不是在某些配置中)


0

最短的代码 

这既处理导航,又处理子导航列表元素。您可以将一个数组传递给单个路径,并且将同时处理两者。

application_helper

# Active page method
def ap(p:);'active' if p.class == Array ? p.map{|m| current_page? m}.any? : (current_page? p) end

视图(html.erb)

<ul class="nav navbar-nav">
  <li class="<%= ap p: home_path %>">Home</li>
  <li class="<%= ap p: account_path %>">Account</li>

  <li class="dropdown <%= ap p: [users_path, new_user_path] %>">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Users</a>
    <ul class="dropdown-menu" role="menu">
      <li class="<%= ap p: users_path %>">Users</li>
      <li class="<%= ap p: new_user_path %>">Add user</li>
    </ul>
  </li>
</ul>

0

在Sinatra上使用红宝石..

我正在使用引导程序裸主题,这是示例导航栏代码。注意元素的类名-> .nav-在Java脚本中被引用。

/ Collect the nav links, forms, and other content for toggling
    #bs-example-navbar-collapse-1.collapse.navbar-collapse
      %ul.nav.navbar-nav
        %li
          %a{:href => "/demo/one"} Page One
        %li
          %a{:href => "/demo/two"} Page Two
        %li
          %a{:href => "/demo/three"} Page Three

在视图页面(或部分页面)中添加此:javascript,这需要在每次页面加载时执行。

haml视图片段->

- content_for :javascript do
  :javascript
      $(function () {
          $.each($('.nav').find('li'), function() {
              $(this).toggleClass('active',
                  $(this).find('a').attr('href') == window.location.pathname);
          });
      });

在JavaScript调试器中,确保您的'href'属性值与window.location.pathname匹配。这与@Zitrax的解决方案稍有不同,后者帮助我解决了问题。


0

基本,无帮助

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

0
  def active_navigation?(controllers_name, actions_name)
   'active' if controllers_name.include?(controller_name) && actions_name.include?(action_name)
  end

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.