Rails 4:如何将 $(document).ready() 与 turbo-links 一起使用

IT技术 javascript jquery ruby-on-rails-4 asset-pipeline turbolinks
2021-01-26 02:31:48

在尝试以“rails 方式”组织 JS 文件时,我在 Rails 4 应用程序中遇到了一个问题。它们以前分散在不同的视图中。我将它们组织成单独的文件并使用资产管道编译它们。但是,我刚刚了解到,当打开涡轮链接时,jQuery 的“就绪”事件不会在后续点击时触发。第一次加载页面时它可以工作。但是当你点击一个链接时,里面的任何东西ready( function($) {都不会被执行(因为页面实际上不会再次加载)。很好的解释:这里

所以我的问题是:确保 jQuery 事件在 turbo-links 打开时正常工作的正确方法是什么?您是否将脚本包装在特定于 Rails 的侦听器中?或者 Rails 有一些魔法让它变得不必要?文档对这应该如何工作有点含糊,特别是在通过清单加载多个文件(如 application.js)方面。

6个回答

这就是我所做的... CoffeeScript:

ready = ->

  ...your coffeescript goes here...

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

最后一行侦听页面加载,这是涡轮链接将触发的。

编辑...添加 Javascript 版本(每个请求):

var ready;
ready = function() {

  ...your javascript goes here...

};

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

编辑 2 ...对于 Rails 5 (Turbolinks 5)page:load成为turbolinks:load并且甚至会在初始加载时被触发。所以我们可以做以下事情:

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

  ...your javascript goes here...

});
那是咖啡脚本吗?我还没学会呢。是否有与您的示例等效的 js 或 jQuery?
2021-03-12 02:31:48
@Emerson 有一个非常有用的网站,有一个明确的名称:js2coffee.org
2021-03-18 02:31:48
仅供参考,您还可以将其应用于多个事件,page:loadready为第一个参数包含一个以空格分隔的字符串。$(document).on('page:load ready', ready);第二个参数只是一个函数,它恰好被命名为ready,遵循这个答案的例子。
2021-03-19 02:31:48
我想我明白了:var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)是否有任何关于两者 .ready'page:load'被触发的担忧
2021-03-28 02:31:48
我可以证实,准备功能并没有被调用两次。如果这是一个困难的刷新,ready事件被触发。如果是 turbolinks 负载,则page:load触发事件。不可能在同一页面上同时触发readypage:load
2021-04-05 02:31:48

我刚刚了解到解决此问题的另一种选择。如果加载jquery-turbolinks宝石它将绑定Rails的Turbolinks事件的document.ready事件,这样你就可以用通常的方式写你的jQuery。您只需在 js 清单文件jquery.turbolinks之后添加jquery(默认情况下:)application.js

添加此 gem 时需要重新启动 Rails 服务器
2021-03-20 02:31:48
很好,谢谢!正是我需要的。铁轨方式。惯例。
2021-04-03 02:31:48
@wildmonkey 这两个答案是相互排斥的。0.o
2021-04-03 02:31:48
请注意,Rails 4 现在默认使用 Turbolinks 5,而 jquery.turbolinks 不支持它!github.com/kossnocorp/jquery.turbolinks/issues/56
2021-04-06 02:31:48
根据文档,您应该添加//= require jquery.turbolinks到清单中(例如 application.js)。
2021-04-07 02:31:48

最近我找到了最简洁易懂的处理方式:

$(document).on 'ready page:load', ->
  # Actions to do

或者

$(document).on('ready page:load', function () {
  // Actions to do
});

编辑
如果您已委托绑定到 的事件document,请确保将它们附加到ready函数之外,否则它们将在每个page:load事件上反弹(导致多次运行相同的函数)。例如,如果您有任何这样的电话:

$(document).on 'ready page:load', ->
  ...
  $(document).on 'click', '.button', ->
    ...
  ...

将它们从ready函数中取出,如下所示:

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

$(document).on 'click', '.button', ->
  ...

绑定到 的委托事件document不需要绑定到ready事件上。

这种方法的缺点是$(document).on( "ready", handler ), deprecated as of jQuery 1.8. jquery/ready
2021-03-12 02:31:48
最简单和最简单的方法来做到这一点。它支持分布在多个文件中的 js 代码,我不必担心它们的包含顺序。比变量赋值干净得多。
2021-03-17 02:31:48
这比创建单独ready()函数的公认答案要简单得多ready函数外部绑定委托事件的解释的奖励赞成
2021-03-22 02:31:48
@Dezi @mfazekas 如果您使用的是早期版本的 jQuery,并且没有 jquery-turbolinks gem,那么这个解决方案是否有效?还是ready使用 gem使部分无效?
2021-03-28 02:31:48
您可能应该使用“page:change”而不是“page:load”,因为无论页面是从服务器加载还是从客户端缓存加载,都会触发前者
2021-04-06 02:31:48

Rails 4 文档中找到了这个,类似于 DemoZluk 的解决方案,但略短:

$(document).on 'page:change', ->
  # Actions to do

或者

$(document).on('page:change', function () {
  // Actions to do
});

如果您有调用的外部脚本,$(document).ready()或者如果您不想重写所有现有的 JavaScript,那么这个 gem 允许您继续使用$(document).ready()TurboLinks:https : //github.com/kossnocorp/jquery.turbolinks

根据新的导轨指南,正确的方法是执行以下操作:

$(document).on('turbolinks:load', function() {
   console.log('(document).turbolinks:load')
});

或者,在咖啡脚本中:

$(document).on "turbolinks:load", ->
alert "page has loaded!"

不监听事件$(document).ready,只会触发一个事件。毫无意外,无需使用jquery.turbolinks gem。

这适用于 rails 4.2 及更高版本,而不仅仅是 rails 5。

任何人都可以确认该"turbolinks:load"事件在 Rails 4.2 中有效吗?turbolinks:事件前缀是在推出Turbolinks和Rails的不使用4.2 IIRC它使用Turbolinks经典"page:change"如果"turbolinks:load"在 Rails 5 之前的应用程序上不起作用,请考虑尝试参见guides.rubyonrails.org/v4.2.7/...
2021-03-14 02:31:48
@EliotSykes 该指南尚未更新。Rails 4.2 现在使用github.com/turbolinks/turbolinks而不是 turbolinks-classic。无论如何,这取决于您在 Gemfile 中指定的内容。希望你能尽快确认:)
2021-03-21 02:31:48
是否alert "page has loaded!"需要缩进才能由回调函数实际运行?
2021-03-23 02:31:48
很好,这对我有用。在这里尝试了解决方案:stackoverflow.com/questions/17881384/...但由于某种原因没有奏效。现在我加载 turbolinks:load 代替
2021-03-25 02:31:48
谢谢@vedant1811。在撰写本文时,我确认新的 Rails 4.2.7 应用程序使用 Turbolinks 5(不是 turbolinks-classic)。阅读本文的开发人员 - 检查您的 Gemfile.lock 是否使用了 turbolinks 版本。如果低于 5.0,则使用page:change或升级 turbolinks。也发现了这个,可能与某些相关,其中 turbolinks 将事件转换为旧的事件名称:github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/...
2021-03-30 02:31:48