Rails 4:如何使用$(document).ready()和turbo-links
我在试图组织JS文件“rails方式”时遇到了Rails 4应用程序中的一个问题。 他们以前分散在不同的意见。 我把它们组织成单独的文件,并用资产pipe道进行编译。 但是,我刚刚了解到,jQuery的“就绪”事件不会触发涡轮链接打开后续点击。 你第一次加载一个页面的作品。 但是当你点击一个链接时, ready( function($) {
任何东西都不会被执行(因为页面实际上并没有再次加载)。
所以我的问题是:什么是正确的方式来确保jQuery事件正常运行,而涡轮链接? 你把脚本包装在一个Rails特定的监听器中吗? 或者,也许铁轨有一些魔法,使之不必要? 这个文档对于如何工作有些模糊,特别是通过像application.js这样的清单加载多个文件。
这是我做的… CoffeeScript:
ready = -> ...your coffeescript goes here... $(document).ready(ready) $(document).on('page:load', ready)
最后一行监听页面加载,这是turbo链接将触发的。
编辑 …添加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... });
我刚刚了解到解决这个问题的另一个select。 如果你加载了jquery-turbolinks
gem,它会把Rails Turbolinks事件绑定到document.ready
事件,所以你可以用通常的方式编写你的jQuery。 您只需在js清单文件(默认情况下为application.js
)中的jquery
后面添加jquery.turbolinks
。
最近我发现了最简单易懂的处理方法:
$(document).on 'ready page:load', -> # Actions to do
要么
$(document).on('ready page:load', function () { // Actions to do });
编辑
如果委托事件绑定到document
,请确保将它们附加到ready
函数之外,否则它们将在每个page:load
上被反弹page:load
事件(导致相同的函数被多次运行)。 例如,如果你有任何这样的电话:
$(document).on 'ready page:load', -> ... $(document).on 'click', '.button', -> ... ...
把他们从ready
function,如下所示:
$(document).on 'ready page:load', -> ... ... $(document).on 'click', '.button', -> ...
绑定到document
委托事件不需要绑定ready
事件。
在Rails 4的文档中发现了这个,类似于DemoZluk的解决scheme,但略短一些:
$(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') });
或者,在coffeescript:
$(document).on "turbolinks:load", -> alert "page has loaded!"
不要听$(document).ready
事件,只有一个事件会被触发。 没有惊喜,没有必要使用jquery.turbolinks的gem。
这适用于导轨4.2及以上版本,不仅仅是导轨5。
注意:请参阅@ SDP的答案,以获得干净的内置解决scheme
我修正如下:
请确保在通过更改包含顺序包含其他应用程序相关的js文件之前包含application.js,如下所示:
// in application.js - make sure `require_self` comes before `require_tree .` //= require_self //= require_tree .
定义一个全局函数来处理application.js
的绑定
// application.js window.onLoad = function(callback) { // binds ready event and turbolink page:load event $(document).ready(callback); $(document).on('page:load',callback); };
现在你可以绑定像这样的东西:
// in coffee script: onLoad -> $('a.clickable').click => alert('link clicked!'); // equivalent in javascript: onLoad(function() { $('a.clickable').click(function() { alert('link clicked'); });
以上都没有为我工作,我解决了这个不使用jQuery的$(document).ready,而是使用addEventListener。
document.addEventListener("turbolinks:load", function() { // do something });
而不是使用variables来保存“就绪”函数并将其绑定到事件上,您可能希望在page:load
触发器时触发ready
事件。
$(document).on('page:load', function() { $(document).trigger('ready'); });
以下是我所做的确保事情不被执行两次:
$(document).on("page:change", function() { // ... init things, just do not bind events ... $(document).off("page:change"); });
我发现使用jquery-turbolinks
gem或$(document).ready
和$(document).on("page:load")
或者使用$(document).on("page:change")
本身的行为意外 -特别是如果你在开发。
我发现下面这篇文章对我很好,详细介绍了以下内容:
var load_this_javascript = function() { // do some things } $(document).ready(load_this_javascript) $(window).bind('page:change', load_this_javascript)
我想我会离开这里为那些升级到Turbolinks 5 :修复你的代码最简单的方法是从:
var ready; ready = function() { // Your JS here } $(document).ready(ready); $(document).on('page:load', ready)
至:
var ready; ready = function() { // Your JS here } $(document).on('turbolinks:load', ready);
参考: https : //github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
要么使用
$(document).on "page:load", attachRatingHandler
或者使用jQuery的.on函数来实现相同的效果
$(document).on 'click', 'span.star', attachRatingHandler
在这里看到更多的细节: http : //srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
<%= link_to 'Edit', edit_article_path(article), 'data-no-turbolink' => true %>
也许你可以像这样使用“准备”,就像closures你的turbolink。
$(document).ready(ready) $(document).on('turbolinks:load', ready)
你必须使用:
document.addEventListener("turbolinks:load", function() { // your code here })
从turbolinks文档 。
首先,安装jquery-turbolinks
gem。 然后,不要忘记把你的application.html.erb
包含Javascript文件移动到它的<head>
。
如此处所述 ,如果您为了速度优化原因而将应用程序JavaScript链接放在页脚中,则需要将其移动到标记中,以便在标记中的内容之前加载它。 这个解决scheme为我工作。
testing了这么多的解决scheme终于来到这个。 这很多你的代码是绝对不会被调用两次。
var has_loaded=false; var ready = function() { if(!has_loaded){ has_loaded=true; // YOURJS here } } $(document).ready(ready); $(document).bind('page:change', ready);
$(document).on 'ready turbolinks:load', -> console.log '(document).turbolinks:load'