我正在构建一个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 页面永远不会工作。我点击几次,最终抛出上面的错误。我仍然不确定为什么,但我怀疑这与涡轮连接有关。
答案 0 :(得分:43)
$(document).ready(function(){
与Turbolinks无法真正合作。 Turbolinks:
...更快地在您的网络应用程序中生成以下链接。它不是让浏览器在每个页面更改之间重新编译JavaScript和CSS,而是使当前页面实例保持活动状态,并仅替换头部中的正文和标题。
因此页面只加载一次,然后根据需要更换部分。由于页面仅加载一次,因此只有在最初访问网站时才会触发$(document).ready()
回调,因此在切换页面时不会获得更多文档就绪事件,因为Turbolinks实际上并未切换页面。来自fine manual:
使用Turbolinks页面会在没有完全重新加载的情况下更改,因此您无法依靠
DOMContentLoaded
或jQuery.ready()
来触发代码。相反,Turbolinks会在文档上触发事件,以便为页面的生命周期提供挂钩。
您可能想要收听其中一个Turbolinks事件:
page:change
页面已被解析并更改为新版本和DOMContentLoaded- [...]
page:load
在加载过程结束时被解雇。
page:change
通常是您正在寻找的内容,因为它是在加载新页面并从Turbolinks页面缓存中恢复页面时触发的。
您可能需要关闭Turbolinks,直到您有时间审核JavaScript的所有并完成全面的QA扫描。您还应该测试网站的速度,看看是否值得使用。
另一个选择是使用jquery.turbolinks为您修补内容。我没有用过这个,但other people正在使用它,效果很好。
答案 1 :(得分:28)
这是一个例子(我喜欢使用的那个)。
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() {
});
一切都适合我。希望这有帮助!