Bootstrap Dropdowns 与 Rails 4 间断工作
Posted
技术标签:
【中文标题】Bootstrap Dropdowns 与 Rails 4 间断工作【英文标题】:Bootstrap Dropdowns working Intermittently with Rails 4 【发布时间】:2015-07-07 15:07:33 【问题描述】:我正在开发一个带有持久导航栏的 Rails 应用程序,包括引导下拉菜单。无论出于何种原因,它偶尔会起作用;在启动或刷新时,下拉菜单将始终有效,在第一次重定向后它们将永远不会工作,之后它似乎基本上在工作和不工作之间交替。当它不起作用时,单击下拉列表时根本不会发生任何事情。我最初的怀疑是 Turbolinks 是罪魁祸首,但我没有 而且我已经能够验证这一点(请参阅下面的编辑)。在花了几个小时阅读之后,我已经尝试了所有我能找到的“明显”修复,但目前还没有运气。
值得注意的是,问题依然存在……
有或没有 turbolinks.jquery 带引导程序或引导链轮 所有最新版本的 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,我将它们与收益一起包含在 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
(只是为了证明我有效地包含了引导程序的其他部分)
/* 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>
【问题讨论】:
你使用浏览器的JS调试工具了吗?控制台可能会给你相关的 JS 错误。 (Chrome 中的 F12 FF 中的 Ctrl-Shift-K) 是的,我在 Chrome 中,我没有发现任何错误。看来我是正确的,这是 Turbolinks 的问题。我禁用了整个 gem,现在一切正常。我仍然想在应用程序中使用 Turbolinks,但我正在相应地更新问题。 我遇到了同样的问题。同样,我的意思是同样的。第一次进入工作,通过链接导航到另一个页面然后它停止工作,然后导航到另一个页面然后它再次工作并继续。有没有机会你弄明白了? 【参考方案1】:我很确定 jquery.turbolinks 必须在 jquery_ujs 之前加载。
在你的 application.js 文件中试试这个:
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .
修订 |删除了无关的加载日志
修订 |添加了
我认为您不应该在导航块中间放置一个容器 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>
【讨论】:
这就是我第一次发现问题时的情况(我只是再次测试以确保我没有发疯)。可悲的是,我尝试过以各种方式扰乱要求,但没有任何顺序起作用。 我正要在加载时上传我的页面源。我有这个工作,。我遇到过 jquery_ujs 和 turbolinks 导致间歇性问题的问题,但这是可以解决的,当然。 感谢您的回复。我可以确认 div 不是问题,因为我有一个使用 This Header 运行的单独 rails 应用程序,其中下拉菜单完美运行(注意,这只是相关的 html;这似乎是对 CodePen 的滥用,但我不会t将其粘贴到评论中)。实际上,我以前曾让一切正常工作,但我找不到任何可观察到的差异。 很公平。那么,工作下拉菜单和间歇工作下拉菜单之间有什么变化? 哈哈,这就是问题所在(它们是两个不同的项目,恰好有相似的标题)。我正在尝试追踪这是否与使用 turbolinks 渲染部分下拉菜单有关——这是我能识别的唯一真正的区别(这可能会改变 javascript 的加载方式是有道理的)。【参考方案2】:您需要首先了解为什么会发生这种情况。当启用 turbolinks 并单击链接时,会触发 page:change
事件,并且会从新加载的 html 重新评估所有 javascript。
这包括在application.js
中加载的引导JavaScript 代码。当引导程序的 javascript 重新加载时,它会中断。您可以通过在 application.js 中的 <script>
标签中使用 data-turbolinks-eval=false
来解决此问题。
用法:
<%= javascript_include_tag 'application', 'data-turbolinks-eval' => false %>
<%= javascript_include_tag params[:controller] %>
【讨论】:
【参考方案3】:我曾经遇到过同样的问题,“下拉菜单”只在第一次工作。我发现我将“发布请求”重定向到“获取请求”路线。这就是为什么引导程序无法正常工作的原因。所以我取消了“重定向”以隔离“发布请求”和“获取请求”。
希望对你有帮助。
【讨论】:
以上是关于Bootstrap Dropdowns 与 Rails 4 间断工作的主要内容,如果未能解决你的问题,请参考以下文章
如何使用bootstrap的daterangepicker插件