Rails 4:如何使用带有turbo-links的$(document).ready()

eme*_*his 417 javascript jquery asset-pipeline turbolinks ruby-on-rails-4

我试图组织JS文件"rails way"时,在我的Rails 4应用程序中遇到了一个问题.他们以前分散在不同的观点中.我将它们组织成单独的文件,并使用资产管道进行编译.但是,我刚刚了解到,当打开turbo-linked时,jQuery的"就绪"事件不会触发后续点击.第一次加载页面时它可以工作.但是当你点击链接时,内部的任何内容ready( function($) {都不会被执行(因为页面实际上并没有再次加载).好解释:这里.

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

Mel*_*emi 550

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

ready = ->

  ...your coffeescript goes here...

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

最后一行侦听页面加载,这是turbo链接将触发的内容.

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

var ready;
ready = function() {

  ...your javascript goes here...

};

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

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

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

  ...your javascript goes here...

});
Run Code Online (Sandbox Code Playgroud)

  • 我可以确认ready函数不会**被调用两次.如果是硬刷新,_only_就会触发`ready`事件.如果是turbolinks加载,_only_会触发`page:load`事件."ready"和"page:load"都不可能在同一页面上触发. (16认同)
  • 仅供参考你也可以通过为第一个参数包含一个以空格分隔的字符串,将它应用于多个事件`page:load`和`ready`.`$(document).on('page:load ready',ready);`第二个参数只是一个函数,恰好命名为`ready`,遵循这个答案的例子. (7认同)
  • 我认为我得到了它:`var ready = function(){...} $(document).ready(ready)$(document).on('page:load',ready)`是否有任何关注*both*`.ready`和''page:load'`被触发? (6认同)
  • @Emerson有一个非常有用的网站,有一个明确的名称:http://js2coffee.org (4认同)
  • 那是咖啡剧本吗?我还没有学到它.有没有js或jQuery等同于你的例子? (3认同)
  • 它是否只在需要时被调用?它在文档准备就绪时调用它,然后在页面加载时调用它(我们假设它来自turbo-link触发器).对? (2认同)

eme*_*his 235

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

  • 请注意,Rails 4现在默认为Turbolinks 5,而jquery.turbolinks则不支持它!请参阅https://github.com/kossnocorp/jquery.turbolinks/issues/56 (20认同)
  • 根据[文档](https://github.com/kossnocorp/jquery.turbolinks),您应该将`// = require jquery.turbolinks`添加到清单(例如application.js). (6认同)
  • 太好了,谢谢!正是我需要的.铁轨方式.惯例. (2认同)

Art*_*soy 201

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

$(document).on 'ready page:load', ->
  # Actions to do
Run Code Online (Sandbox Code Playgroud)

要么

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

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

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

将它们从ready功能中取出,如下所示:

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

$(document).on 'click', '.button', ->
  ...
Run Code Online (Sandbox Code Playgroud)

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

  • 这比创建单独的`ready()`函数的接受答案要简单得多.Bonus upvotes解释了在"ready"函数之外绑定委托事件. (9认同)
  • 您应该使用"page:change"而不是"page:load",因为[无论页面是从服务器加载还是从客户端缓存加载,都会触发前者](https://github.com/rails/turbolinks /#事件). (3认同)

mig*_*igu 91

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

$(document).on 'page:change', ->
  # Actions to do
Run Code Online (Sandbox Code Playgroud)

要么

$(document).on('page:change', function () {
  // Actions to do
});
Run Code Online (Sandbox Code Playgroud)

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


ved*_*ant 78

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

$(document).on('turbolinks:load', function() {
   console.log('(document).turbolinks:load')
});
Run Code Online (Sandbox Code Playgroud)

或者,在coffeescript中:

$(document).on "turbolinks:load", ->
alert "page has loaded!"
Run Code Online (Sandbox Code Playgroud)

不要听这个事件$(document).ready,只会触发一个事件.没有惊喜,不需要使用jquery.turbolinks gem.

这适用于导轨4.2及以上,而不仅仅是导轨5.

  • 谢谢@ vedant1811.在撰写本文时,我确认新的Rails 4.2.7应用程序使用的是Turbolinks 5(不是turbolinks-classic).阅读此内容的开发人员 - 检查您的Gemfile.lock以获取所使用的turbolinks版本.如果它小于5.0,那么使用`page:change`或升级turbolinks.也发现这一点,可能与某些相关,其中turbolinks将事件转换为旧的事件名称:https://github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/compatibility.coffee (3认同)

sle*_*led 10

注意:请参阅@ SDP的答案,了解干净的内置解决方案

我把它固定如下:

通过更改include顺序,确保在包含其他应用程序相关js文件之前包含application.js,如下所示:

// in application.js - make sure `require_self` comes before `require_tree .`
//= require_self
//= require_tree .
Run Code Online (Sandbox Code Playgroud)

定义一个处理绑定的全局函数 application.js

// application.js
window.onLoad = function(callback) {
  // binds ready event and turbolink page:load event
  $(document).ready(callback);
  $(document).on('page:load',callback);
};
Run Code Online (Sandbox Code Playgroud)

现在你可以绑定像:

// in coffee script:
onLoad ->
  $('a.clickable').click => 
    alert('link clicked!');

// equivalent in javascript:
onLoad(function() {
  $('a.clickable').click(function() {
    alert('link clicked');
});
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是最干净的,因为你只需要在一个地方添加它,而不是每个coffeescript文件.干得好! (2认同)

小智 8

以上都不适用于我,我通过不使用jQuery的$(document).ready来解决这个问题,但是使用addEventListener.

document.addEventListener("turbolinks:load", function() {
  // do something
});
Run Code Online (Sandbox Code Playgroud)


Suk*_*iga 6

$(document).on 'ready turbolinks:load', ->
  console.log '(document).turbolinks:load'
Run Code Online (Sandbox Code Playgroud)


小智 5

您必须使用:

document.addEventListener("turbolinks:load", function() {
  // your code here
})
Run Code Online (Sandbox Code Playgroud)

来自turbolinks doc