Rails6 remote:true链接不触发turbolinks:click、ajaxStart事件 spinner异常
问题背景
技术栈
- Rails 6
- Turbolinks 5
- Webpacker
目标需求
点击带remote: true属性的链接时显示加载spinner,请求完成后隐藏spinner。
已尝试的失效方案
方案1:Turbolinks事件
链接生成代码:
<%=link_to 'Documents', documents_path, remote: true %>
在application.html.erb的<head>标签内插入以下代码:
$(document).on("turbolinks:load", function(){ alert('turbolinks load works'); //$(".sk-cube-grid").hide(); }); $(document).on("turbolinks:click", function(){ alert('this doesnt work'); //$(".sk-cube-grid").show(); });
问题:turbolinks:load可以正常触发,turbolinks:click无响应。
方案2:jQuery全局ajax事件
$(document).ajaxStart(function(){ alert('started ajax - doesnt work'); }); $(document).ajaxStop(function(){ alert('stopped ajax - doesnt work'); })
问题:两个事件完全不生效。
调整后未完全生效的方案
var page_loaded = function() { $(".sk-cube-grid").hide(); }; $(document).on("read page:load", page_loaded); $(document).on("ajax:send", "a", function(xhr){ $('.sk-cube-grid ').show() }).on("ajax:complete", "a", function(data, status, xhr) { $(".sk-cube-grid").hide(); });
问题:ajax:send触发时spinner可以正常显示,但ajax:complete或ajax:success触发时spinner不会隐藏。
解决方案
失效原因说明
turbolinks:click事件只会在普通<a>标签跳转、Turbolinks接管页面渲染逻辑时触发,带remote: true的链接由Rails UJS接管处理异步请求,不会触发Turbolinks跳转类事件。- Rails 5.1+默认使用
@rails/ujs替代依赖jQuery的jquery-ujs,底层通过fetch API实现异步请求,不会触发jQuery的全局ajax事件,因此ajaxStart/ajaxStop完全不生效。
修正后的代码
首先确认你已经在webpack入口文件app/javascript/packs/application.js中正确初始化了@rails/ujs:
import Rails from "@rails/ujs" Rails.start()
将原先的事件绑定逻辑替换为以下内容:
// 页面加载完成后隐藏spinner,兼容Turbolinks 5 $(document).on("turbolinks:load", function() { $(".sk-cube-grid").hide(); }); // 仅绑定带remote: true属性的a标签的Rails UJS异步事件 $(document) .on("ajax:send", "a[data-remote='true']", function() { $(".sk-cube-grid").show(); }) // 覆盖请求完成、成功、失败三种场景,避免请求异常时spinner一直显示 .on("ajax:complete ajax:success ajax:error", "a[data-remote='true']", function() { $(".sk-cube-grid").hide(); });
这样修改后,点击remote: true链接时spinner会正常显示,不管请求是成功、失败还是完成,都会自动隐藏spinner。
内容的提问来源于stack exchange,提问作者Kamal Agbaria
相关产品推荐
相关产品推荐

