Ruby on Rails中jquery_ujs组件拖慢速度的问题解决
jquery_ujs对rails来说,是一个非常重要的组件,它包含在rails的默认组件之中。
jqueryujs包含一些非常便捷的功能,比如确认对话框、触发ajax、自动禁用表单提交按钮等,本文主要讨论的是触发ajax的功能。
通过添加简单的标签属性,jqueryujs可以把一个普通的链接或者表单转换成ajax提交,而不需要写JavaScript代码。
<%=link_to'关闭项目',close_project_path(project),remote:true,method::post%>
上面的代码会生成如下的代码
<ahref="/projects/1/close"data-remote="true"data-method="post">关闭项目</a>
当用户点击后,它会触发一个指向地址/projects/1/close,method为post的ajax请求,而不是get的普通请求,这样使得实现ajax调用变得非常便捷。
网速慢导致的问题
事情并不都是美好的,在网速比较慢的时候,jqueryujs的这个实现会出问题,如果文档还没有加载完成,用户就点击了链接,页面会发起一个到链接地址的GET请求,页面会跳转,但指向该地址的GET请求可以并不存在,这样就会出错。
有用户有提过一个相关的Issue,但是开发者并没有受理,然而网速慢是中国的国情,问题我们还是得处理,借助于CSS3的一些特性,这个问题其实也不难解决。
pointer-events pointer-events:none; Theelementisneverthetargetofmouseevents;however,mouseeventsmaytargetitsdescendantelementsifthosedescendantshavepointer-eventssettosomeothervalue.Inthesecircumstances,mouseeventswilltriggereventlistenersonthisparentelementasappropriateontheirwayto/fromthedescendantduringtheeventcapture/bubblephases.
这个属性可以禁止元素的点击事件,因为一般CSS是先加载的,我们只要控制在页面加载完成之前给jqueryujs相关的元素应用pointer-events:none;样式,在页面加载完成后再去除该样式,就可以解决网速慢的情况下,页面没有加载完成时用户点击rmote链接导致的错误了。
解决方案
添加如下的全局样式,默认情况下含有data-remote和data-method属性的标签不可点击,除非body元素含有名为ready的cssclass。
[data-remote],[data-method]{ pointer-events:none; button,input[type=submit]{ pointer-events:none; } } body.ready{ [data-remote],[data-method]{ pointer-events:auto; button,input[type=submit]{ pointer-events:auto; } } }
然后通过段简单的脚本让页面加载后给body元素添加readyclass
$(document).ready-> $('body').addClass('ready')
于是,问题轻松的就解决了。