Rails资产管道:JavaScript被执行两次

6

我的JavaScript被执行了两次。当我运行Chrome调试器时,我注意到单独的JavaScript文件会在第一次执行代码后,application.js文件会再次执行代码。

我认为这是因为最近我关闭了预编译,因为我在Heroku上遇到了问题。在此之后,我运行了rake assets:precompile

3个回答

11

Turbolinks

如果您在资产管道中包含了Turbolinks,那么您可能会遇到问题。不过这并不一定是问题的原因。

Turbolinks旨在通过使用ajax加载新页面的<body>标记,保持<head>标记不变,从而加快页面加载时间。这样让应用程序只加载所需的HTML,但会影响页面上的JS。

如果您的JS被触发两次,这可能是Turbolinks干扰您的JS的迹象。由于您没有提供任何来自logs的示例,我无法提供具体信息,但您应该可以通过从您的layoutapplication清单JS文件中删除turbolinks包含语句来测试此问题:

#app/views/layouts/application.html.erb
= javascript_include_tag "application", "data-turbolinks-track" => false

#app/assets/javascripts/application.js
//= require turbolinks -> remove this line
如果你这样做了,请重新启动服务器并重新加载相关页面。如果还是出现错误的功能,那么这意味着Turbolinks不是问题所在(你应该重置所有更改过的内容)。
--
事件
你可能遇到的另一个问题是如何调用/触发事件。这可能是由于多种原因造成的,但你应该确保检查你如何调用JS。
#app/assets/javascripts/application.js
$(document).on("click", ".element", function(){
    //your stuff here
});

我们现在总是从 document 元素的 DOM 进行委派。虽然这可能会导致一些资源问题,但我们发现这使得Rails应用程序更加健壮,因为它允许您真正识别页面上的元素。

如果您正在尝试从DOM上的单个对象触发事件,则可能会发现JS会“捕获”事件两次(出于某种原因),从而导致问题。请尝试委派被调用两次的事件

--

函数

最后,您的functions可能是问题所在。

如果您有任何匿名函数或特定事件的函数,您需要确保它们能够正确调用。您应该使用JS中的页面事件Turbolinks来实现此目的:

#app/assets/javascripts/application.js
var your_function = function() {
    //stuff here
};

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

我没有使用turbolinks,除非它在Rails 3.2.13中自动包含。 - user2158382
仅翻译文本内容:或者除非已包含在Bootstrap 3中 - user2158382
3
感谢你出色的解释,Richard。 - Jake Smith

1

1

我遇到了这个问题,是因为资产管道同时包含了jquery、jquery-ujs和rails-ujs:

//= require jquery
//= require jquery_ujs
//= require rails_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .

删除了rails_ujs后,一切都正常了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接