Skip to main content
 首页 » 编程设计

jquery之Bootstrap 下拉菜单与 Rails 4 间歇性工作

2026年07月28日5bonelee

我正在开发一个带有持久导航栏(包括 Bootstrap 下拉菜单)的 Rails 应用程序。无论出于何种原因,它偶尔会工作;在启动或刷新时,下拉菜单将始终有效,在第一次重定向后,它们将永远不会工作,之后它似乎基本上在工作和不工作之间交替。当它不起作用时,单击下拉菜单时什么也不会发生。我最初怀疑 Turbolinks 是罪魁祸首,但我没有 并且我已经能够验证这一点(请参阅下面的编辑)。在花了几个小时阅读之后,我尝试了所有能找到的“明显”修复方法,但目前还没有成功。

值得注意的是,问题仍然存在......

  • 有或没有turbolinks.jquery
  • 带有 Bootstrap 或 Bootstrap 链轮
  • 跨所有最新版本的 bootstrap-sass gem
  • 是否重新排列我的 application.js 文件
  • 将 application.js data-turbolinks-track 设置为 true 或 false
  • 无论是开发还是生产

编辑:

通过完全禁用 Turbolinks(删除 Turboling 和 jquery-turbolinks gem,删除 application.js 中对它们的引用,并删除 application.html.erb 中的 data-turbolinks-track 属性),我没有工作下拉菜单。也就是说,我仍然想知道为什么这不起作用,因为我希望在发布之前重新启用涡轮链接。/编辑结束

这些是我认为相关的文件:

application.js

请注意//= 需要 tree 。不存在。这是故意的(我有许多特定于页面的 JavaScript,我将它们与 yield 一起包含到 application.html.erb 中)。

//= require jquery 
//= require jquery_ujs 
//= require jquery.turbolinks 
//= require turbolinks 
//= require bootstrap-sprockets 

Gemfile.rb

source 'https://rubygems.org' 
 
 
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 
gem 'rails', '4.2.0' 
 
# Bootstrap 
gem 'bootstrap-sass', '3.3.4.1' 
gem 'autoprefixer-rails' 
 
# Use SCSS for stylesheets 
gem 'sass-rails', '~> 5.0' 
 
# Use Uglifier as compressor for JavaScript assets 
gem 'uglifier', '>= 1.3.0' 
 
# Use CoffeeScript for .coffee assets and views 
gem 'coffee-rails', '~> 4.1.0' 
 
# Use jquery as the JavaScript library 
gem 'jquery-rails' 
 
# Make Turbolinks play nice with JQuery 
gem 'jquery-turbolinks' 
 
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 
gem 'turbolinks' 
 
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 
gem 'jbuilder', '~> 2.0' 
 
# bundle exec rake doc:rails generates the API under doc/api. 
gem 'sdoc', '~> 0.4.0', group: :doc 
 
# Gems for interfacing with SQL Server 
gem 'tiny_tds' 
gem 'activerecord-sqlserver-adapter' 
 
# Use ActiveModel has_secure_password 
gem 'bcrypt', '~> 3.1.7' 
 
 
group :development, :test do 
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console 
  gem 'byebug' 
 
  # Access an IRB console on exception pages or by using <%= console %> in views 
  gem 'web-console', '~> 2.0' 
 
  # Test DB 
  gem 'sqlite3' 
end 
 
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem 
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 

application.css.scss

(只是为了证明我有效地包含了 Bootstrap 的其他部分)

/* CHARSET 
-------------------------------------------------- */ 
@charset "utf-8"; 
 
 
/* IMPORTS - BOOTSTRAP 
-------------------------------------------------- */ 
@import "bootstrap-sprockets"; 
@import "bootstrap"; 
 
 
/* IMPORTS - SCSS MIXINS 
-------------------------------------------------- */ 
@import "mixins/*"; 
 
 
/* IMPORTS - LAYOUT CSS 
-------------------------------------------------- */ 
@import "layout"; 
 
 
/* IMPORTS - CONTROLLERS' CSS 
-------------------------------------------------- */ 
@import "controllers/*"; 

application.html.erb

请注意,有两种不同的可能的导航栏(一个在登录时,另一个在注销时)从部分呈现。只有 _nav_logged_in.html.erb 包含下拉菜单,接下来我将包含它。

另请注意,所有 javascript 加载均位于文件底部。

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <meta name="description" content="This is APO Lite in the context of Ruby on Rails"> 
    <meta name="author" content="Connor McKee"> 
    <title>APO Lite</title> 
 
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %> 
    <%= csrf_meta_tags %> 
 
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> 
    <!--[if lt IE 9]> 
        <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> 
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> 
    <![endif]--> 
</head> 
 
<body role="document"> 
 
<!-- Fixed navbar --> 
<nav class="navbar navbar-inverse navbar-fixed-top"> 
    <div class="container"> 
        <div class="navbar-header"> 
            <%= link_to "APO Lite", root_url, id: "navLogo", class: "navbar-brand" %> 
        </div> 
 
 
        <% if logged_in? %> 
            <%= render 'layouts/nav_logged_in' %> 
        <% else %> 
            <%= render 'layouts/nav_logged_out' %> 
        <% end %> 
 
        <!--/.nav-collapse -->  
    </div> 
</nav> 
 
<header class="jumbotron subhead <%= 'expandedJumbotron' if current_page? root_url %>" id="overview"> 
  <div class="container"> 
    <% if has_project? && !current_page?( root_url ) %> 
        <h1><%= current_project.name %></h1> 
        <p class="lead"><%= current_project.description %></p> 
    <% else %> 
        <h1>WELCOME TO APO LITE</h1> 
        <p class="lead">Your Journey towards a Better Project Management Experience Starts Here</p> 
    <% end %> 
  </div> 
</header> 
 
<div class="container"> 
 
    <!-- Page Description a.k.a. "Context" --> 
    <% if content_for?(:context) %> 
        <div class="row" id="context"> 
            <div class="col-md-12"> 
                <%= yield :context %> 
            </div> 
        </div> 
    <% end %> 
 
    <!-- Page Content --> 
    <%= yield %> 
 
    <!-- This is debug info --> 
    <% if Rails.env.development? %> 
        <div class="row"> 
            <div class="col-md-12"> 
                <%= debug(params) %> 
            </div> 
        </div> 
    <% end %> 
 
</div> 
 
 
<!-- Javascripts --> 
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 
<% if content_for?(:page_js) %> 
    <%= yield :page_js %> 
<% end %> 
 
</body> 
</html> 

_nav_logged_in.html.erb

最后,这是下拉菜单本身。

<div id="navbar" class="navbar-collapse collapse"> 
    <ul class="nav navbar-nav"> 
        <li> 
            <% if has_project? %> 
                <%= link_to current_project.name, current_project %> 
            <% else %> 
                <a href="#about">My Project Name</a> 
            <% end %> 
        </li> 
        <li class="dropdown"> 
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Administer<span class="caret"></span></a><!--class="active"--> 
            <ul class="dropdown-menu" role="menu"> 
                <li><a href="#">Questionnaires</a></li> 
                <li><a href="#">Reports</a></li> 
            </ul> 
        </li> 
        <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Support<span class="caret"></span></a><!--class="active"--> 
            <ul class="dropdown-menu" role="menu"> 
                <li><a href="#">Documentation</a></li> 
                <li><a href="#">Help Desk</a></li> 
            </ul> 
        </li> 
    </ul> 
    <ul class="nav navbar-nav navbar-right"> 
        <li><%= link_to "Log out", logout_path, method: "delete" %></li> 
        <li class="dropdown"> 
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><%= current_user.first_name %><span class="caret"></span></a><!--class="active"--> 
            <ul class="dropdown-menu" role="menu"> 
                <li><%= link_to "My Profile", current_user %></li> 
                <li><%= link_to "Log out", logout_path, method: "delete" %></li> 
            </ul> 
        </li> 
    </ul> 
 
</div> 

最后,这是应用程序运行时如何加载脚本

这是与 bootstrap-sprockets 一起使用的,但 bootstrap 本身会导致同样的问题。请注意任何地方都没有重复。

<!-- Javascripts --> 
<script src="/assets/jquery.self-d03a5518f45df77341bdbe6201ba3bfa547ebba8ed64f0ea56bfa5f96ea7c074.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/jquery_ujs.self-8e98a7a072a6cee1372d19fff9ff3e6aa1e39a37d89d6f06861637d061113ee7.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/jquery.turbolinks.self-176b9819f30444d441e820bbccd3264fe57753aeafd54dec732b0dbc77129a2a.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/turbolinks.self-c37727e9bd6b2735da5c311aa83fead54ed0be6cc8bd9a65309e9c5abe2cbfff.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/affix.self-68d1a5161d04ca9fe1b9d9f4114d9426c7798bf90f2703a97aca35c8113469bb.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/alert.self-15ce09eba576e56db3edfd87accc0ff48823df915169e350b4fd97290f96aee1.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/button.self-37c62bff1d75f86f3348b8679873d5156d8b9938b62841038dca21690f4740f1.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/carousel.self-9aaab1a477b9c1156bab751cb8da47f77dace6da88eef8ae830e60f3cff3a8be.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/collapse.self-eeece00cd06a3d7cc071ab7845b549d4991edd0f0895e4be70fe40bac2fb5f4b.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/dropdown.self-a3998e7ca949c04cb86b5c635deb0abcc7a24dc02e81be66b8acfef02d811e45.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/modal.self-f2759e138605770e60526c00c6d86cbb3378da203641f9d6b204c9f0192b9267.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/scrollspy.self-5ea180afe4404f83fc97d997833f2edefd34475b0b5ddab310e27abc2bbd5f2f.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/tab.self-e1bba7115c90301056ee94c4716de2fcbe4498015def2dab9ff9879f339bd245.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/transition.self-7742dca5e6acf313fbb217811b48468282cddf1a9baea5c89ec92e367ef242cb.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/tooltip.self-c3b5c16f394ab9c0391db4431aac4f2d2ddf1bba4c5d3228ed343de05ecc8e83.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap/popover.self-2674d99c3ab0415dba0b958a80b3840f70ff6368b155d890306c0291be49453b.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/bootstrap-sprockets.self-fbfa5ad7d9aa0afe439ec4ff3883acc4cb92b62cb67c40d674320c9aa1d4642d.js?body=1" data-turbolinks-track="false"></script> 
<script src="/assets/application.self-f98a0dd27ad1c55b2b9cfe97296d4887e5d4a4535b3bbbf9130c1050771738b2.js?body=1" data-turbolinks-track="false"></script> 

请您参考如下方法:

我非常确定 jquery.turbolinks 必须在 jquery_ujs 之前加载。

在您的 application.js 文件中尝试一下:

//= require jquery 
//= require jquery.turbolinks 
//= require jquery_ujs 
//= require bootstrap 
//= require turbolinks 
//= require_tree . 

修订 |删除了无关的加载日志

修订 |添加

我认为你不应该在导航 block 的中间有一个容器 div。您可能想尝试仅复制/粘贴这个简单的示例结构(来自工作应用程序)。

<ul class="nav navbar-nav  pull-right"> 
 
      <li class="dropdown"> 
        <a href="#" class="dropdown-toggle" data-toggle="dropdown"> 
          Dropdown <b class="caret"></b> 
        </a> 
        <ul class="dropdown-menu"> 
            <li><%= link_to "A", some_working_url %></li> 
            <li><%= link_to "A", some_working_url %></li> 
            <li><%= link_to "A", some_working_url %></li> 
 
        </ul> 
      </li> 
    </li> 
     ... 
   </ul>