多次连续点击导致Ajax重复提交
有个类似商品管理的功能,商品通过execle 文件导入商品,然后“检查”导入的数据的合法性功能。
由于导入的商品的数量一般较大,所以点击一次“检查”按钮,每次的执行时间相对较长,用户往往会进行多次点击“检查“”按钮,造成程序开销较大,甚至程序卡死,或者因为ajax 提交的回调函数等待执行时间过长,导致页面假死或崩溃。所以必须要给类似这样的按钮加上“控制”------在ajax 执行时,使按钮失效(不能点击),待后太代码执行完毕后,再回调函数中处理一下这个button,使之可以继续点击。
这样的功能貌似很好实现,但是期间遇到个小问题,自己困惑了个把小时,所以拿出自己的经历,以便其他遇到此类问题的小伙伴们节约更多时间,下面贴关键代码:
<button type="button" id="check" class="btn_divBtn del float_btn" href="#">检查</button>
代码片段A:
$("#check").click(function(){ $("#check").addClass(disabled).attr(disabled, true); //---------------------------17行 $.ajax({ url:"${base}/impstkmas/check.jhtml", type : post, dataType:json, async:false, success: function(data){ $("#check").removeClass(disabled).attr(disabled, false); //-----------------------------24行 if(data.success){ $("#grid-table").jqGrid(setGridParam,{ postData:{} //发送数据 }).trigger("reloadGrid"); //重新载入 $.jBox.tip(检查完成!, success); }else{ $.jBox.tip(data.msg, error); } } }); });
代码片段B:
$("#check").click(function(){ $(this).addClass(disabled).attr(disabled, true); //--------------------------------17 行 $.ajax({ url:"${base}/impstkmas/check.jhtml", type : post, dataType:json, async:false, success: function(data){ $(this).removeClass(disabled).attr(disabled, false); //--------------------------------24 行 if(data.success){ $("#grid-table").jqGrid(setGridParam,{ postData:{} //发送数据 }).trigger("reloadGrid"); //重新载入 $.jBox.tip(检查完成!, success); }else{ $.jBox.tip(data.msg, error); } } }); });
大家比较上面两段代码,可以看出区别:
A段代码是正确的执行,B段代码是不能正确执行的。开始特别疑惑:
$(this).addClass(disabled).attr(disabled, true); 和 $(this).removeClass(disabled).attr(disabled, false); 一个是使button失效,一个是使button 生效,为什么只能失效,不能回复生效。
原因相信大家已经看出来了,这里是用在ajax 里的,我急竟然忽略了ajax 的最大特点:“异步”!!!。 没错,就是这个特点导致,17 行的代码执行完了,是可以的,因为$(this) 元素是被认识的。而 24 行的代码,死活就是执行不了,因为他用在了回调函数里了,此时再用$(this),代码已经不认识$(this)指的是哪个元素了,所以执行不了。
总结一句话就是,17 行的 $(this) 和 24 行的 $(this) 是不一样的,所以,大家还是尽量不偷懒,用元素选择器在选择出来的对象是可定不会错的!