有个类似商品管理的功能,商品通过execle 文件导入商品,然后“检查”导入的数据的合法性功能。
由于导入的商品的数量一般较大,所以点击一次“检查”按钮,每次的执行时间相对较长,用户往往会进行多次点击“检查“”按钮,造成程序开销较大,甚至程序卡死,或者因为ajax 提交的回调函数等待执行时间过长,导致页面假死或崩溃。所以必须要给类似这样的按钮加上“控制”------在ajax 执行时,使按钮失效(不能点击),待后太代码执行完毕后,再回调函数中处理一下这个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) 是不一样的,所以,大家还是尽量不偷懒,用元素选择器在选择出来的对象是可定不会错的!