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

eme*_*his 47 javascript turbolinks ruby-on-rails-4

我正在构建一个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 .
Run Code Online (Sandbox Code Playgroud)

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

Uncaught TypeError: Cannot read property 'position' of null 
turbolinks.js?body=1:75
Run Code Online (Sandbox Code Playgroud)

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

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

更新!

我的项目脚本不起作用时,它是可预测的.第一页加载每次都有效.然后我点击一个链接到一个使用我的project.js行为的新页面,第二个页面永远不会工作.我点击几次,最终抛出上面的错误.我仍然不确定为什么,但我怀疑这与涡轮连接有关.

mu *_*ort 43

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

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

因此页面只加载一次,然后根据需要更换部分.由于页面只加载一次,您的$(document).ready()回调仅在最初访问站点时触发,因此在切换页面时您不会获得更多文档就绪事件,因为Turbolinks实际上并未切换页面.从精细手册:

使用Turbolinks页面将在没有完全重新加载的情况下更改,因此您无法依赖DOMContentLoadedjQuery.ready()触发代码.相反,Turbolinks会在文档上触发事件,以便为页面的生命周期提供挂钩.

您可能想要收听Turbolinks事件之一:

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

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

您可能希望关闭Turbolinks,直到您有时间查看所有 JavaScript并且您已完成全面的QA扫描.您还应该测试您网站的速度,看看它是否值得使用.

另一个选择是使用jquery.turbolinks为你修补东西.我没有用过这个,但是其他人正在使用它以达到良好的效果.

  • Turbolinks文档说它在`document`上触发了自己的`page:...`事件,所以`$(document).on('page:change',function(){...})`等等. (3认同)

Ole*_*røm 28

railscast已经提供了解决方案

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

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

$(document).ready(ready)
$(document).on('page:load', ready)
Run Code Online (Sandbox Code Playgroud)

还有一个宝石可以解决这个问题,让你以旧的方式继续这样做.它工作得很好:)

  • 不,这是CoffeeScript.有关如何翻译的示例,请将上述代码粘贴到此页面的右侧文本框中:http://js2.coffee/ (2认同)
  • 请注意,这不适用于rails 5. (2认同)