【问题标题】:Rails 4 turbo-link prevents jQuery scripts from workingRails 4 turbo-link 阻止 jQuery 脚本工作
【发布时间】:2013-09-17 03:01:04
【问题描述】:

我正在构建一个 Rails 4 应用程序,并且我有一些分散的 js 文件,我试图将它们包含在“rails 方式”中。我将 jquery 插件移到 /vendor/assets/javascripts 中,并更新了清单 (application.js) 以要求它们。当我在本地加载页面时,我看到它们显示正确。

但是,我从一个已编译的脚本中得到了不一致的行为。我有一个名为projects.js 的特定于控制器的js 文件,它在application.js 中通过使用require_tree . 引用:

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

我看到文件包含正确,并且它可以工作......一半时间。另一半时间,projects.js 中的东西似乎没有做任何事情(主要是 jquery 动画和一些 ajax 请求)。当它不起作用时,我会单击几次按钮,什么都不会发生,然后我会抛出这个错误:

Uncaught TypeError: Cannot read property 'position' of null 
turbolinks.js?body=1:75

当脚本位于单独的视图中时(错误的方式),这从未发生过,所以我相当确定问题不在于我的 javascript 代码。另一个可能相关的细节是 projects.js 中的内容被包裹在 $(document).ready(function(){ 中。另外,我正在开发模式下进行测试,因此资产管道不会组合 javascripts 和 css。

知道这里发生了什么吗?我是 Rails 新手,但我已尽力遵守所有惯例。

更新!

这是可以预见的什么时候我的项目脚本不工作。第一个页面加载每次都有效。然后我单击一个链接到一个使用我的 project.js 行为的新页面,而 second 页面永远不会工作。我点击了几次,最终抛出了上面的错误。我仍然不确定为什么,但我怀疑这与 turbo-linking 有关。

【问题讨论】:

标签: javascript ruby-on-rails-4 turbolinks


【解决方案1】:

$(document).ready(function(){ 不适用于 Turbolinks。 Turbolinks:

... 使您的 Web 应用程序中的以下链接更快。它不会让浏览器在每个页面更改之间重新编译 JavaScript 和 CSS,而是保持当前页面实例处于活动状态并仅替换头部中的正文和标题。

所以页面只加载一次,然后根据需要替换部分。由于页面只加载一次,您的$(document).ready() 回调仅在最初访问该站点时触发,切换页面时您不会收到更多文档就绪事件,因为 Turbolinks 实际上并没有切换页面。来自fine manual

使用 Turbolinks 页面会在没有完全重新加载的情况下发生变化,因此您不能依赖 DOMContentLoadedjQuery.ready() 来触发您的代码。相反,Turbolinks 会在文档上触发事件,以提供进入页面生命周期的挂钩。

您可能想监听其中一个 Turbolinks 事件:

  • page:change 页面已解析并更改为新版本并在 DOMContentLoaded 上
  • [...]
  • page:load 在加载过程结束时触发。

page:change 通常是您要查找的内容,因为它是在加载新页面并从 Turbolinks 页面缓存中恢复页面时触发的。

您可能需要关闭 Turbolinks,直到您有时间查看 所有您的 JavaScript 并且完成了完整的 QA 扫描。您还应该测试您网站的速度,看看它是否值得使用。

另一种选择是使用jquery.turbolinks 为您修补东西。这个我没用过,不过other people用的效果很好。

【讨论】:

  • 谢谢!!您会从我的更新(刚刚添加)中看到,您所说的与我所看到的完全吻合。但是,对于我的“特定于页面”的 js 代码应该包含在什么(如果有的话)中,我有点困惑。例如,如果我将所有内容都放在 application.js 中,我应该直接跳入事件等吗? No $(document).ready...?
  • 再想一想,你的答案解决了这个问题的问题。 Turbo-linking 正在阻止就绪事件。所以我创建了一个新问题来解决应该如何完成的后续问题:stackoverflow.com/questions/18770517/…
  • Turbolinks 文档说它会在 document$(document).on('page:change', function() { ... }) 等上触发自己的 page:... 事件。
  • 对于rails 5,你可以简单地说$(document).on('turbolinks:load', function() { ... });
【解决方案2】:

railscast 已经提供了解决方案

这是一个例子(我喜欢用的那个)。

ready = ->
  # ..... your js

$(document).ready(ready)
$(document).on('page:load', ready)

There is also a gem 解决了这个问题,让您可以继续使用旧方法。效果很好:)

【讨论】:

  • 这是使用 Haml 吗?我不确定如何将您的答案翻译成普通的 javascript
  • 不,这是 CoffeeScript。有关如何翻译的示例,请将上述代码粘贴到此页面的右侧文本框中:js2.coffee
  • 伟大的宝石呼吁!
【解决方案3】:

我意识到这个答案是 REAAAAAAALLLLLLLYYYYY 迟到了......但我想我会添加它。

我上周刚遇到这个问题..在试图让 Foundation 工作时..

首先我添加了:

gem 'jquery-turbolinks'

然后将其放在application.js 中,如下所示:

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

然后我在它下面添加了这个:

$(document).on('turbolinks:load', function() {

});

一切都对我有用。希望这会有所帮助!

【讨论】:

  • 你真的不再需要jquery-turbolinks gem。新的 turbolinks 5 工作正常
猜你喜欢
  • 2017-02-25
  • 2019-08-20
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
相关资源
最近更新 更多