Rails 4 turbo-link阻止jQuery脚本工作

时间:2013-09-12 15:59:59

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

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

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

//= 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 页面永远不会工作。我点击几次,最终抛出上面的错误。我仍然不确定为什么,但我怀疑这与涡轮连接有关。

3 个答案:

答案 0 :(得分:43)

$(document).ready(function(){与Turbolinks无法真正合作。 Turbolinks

  

...更快地在您的网络应用程序中生成以下链接。它不是让浏览器在每个页面更改之间重新编译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正在使用它,效果很好。

答案 1 :(得分:28)

railscast

已提供此解决方案

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

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

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

There is also a gem解决了这个问题的方式让你继续以旧的方式去做。它的效果非常好:))

答案 2 :(得分:1)

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

我上周刚刚遇到这个问题..试图让基金会工作..

首先我补充说:

gem 'jquery-turbolinks'

然后将其放在application.js中,如此:

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

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

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

});

一切都适合我。希望这有帮助!