我們在訪問有的網站,輸入表單完成以后,單擊提交按鈕進行提交以后,提交按鈕就會變為灰色,用戶不能再單擊第二次,直到重新加載頁面或者跳轉。這樣,可以一定程度上防止用戶重復提交導致應用程序上邏輯錯誤。
還有很多其他的方式進行防止重復點擊提交,如
1、定義標志位:
點擊觸發請求后,標志位為false量;請求(或者包括請求后具體的業務流程處理)后,標志位為true量。通過標志位來判斷用戶點擊是否具備應有的響應。
2、卸載及重載綁定事件:
點擊觸發請求后,卸載點擊事件;請求(或者包括請求后具體的業務流程處理)后,重新載入綁定事件。
3、替換(移除)按鈕DOM
點擊觸發請求后,將按鈕DOM對象替換掉(或者將之移除),自然而然此時不在具備點擊事件;請求(或者包括請求后具體的業務流程處理)后,給新的按鈕DOM定義點擊事件。
不妨引深來看,它不一定發生在表單的提交事件上,同樣可以發生在ajax的異步請求上。有效地在web客戶端采用一定機制去防止重復點擊提交,將大大減輕服務器端壓力。
那么,我們就不妨從表單提交及ajax的兩種不同請求的處理過程中,來試試如何防止重復點擊提交。
表單提交
<form action="login.do" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" onclick="this.disabled=true; this.value='登錄中...'; this.form.submit();" value="登錄" />
</form>
單擊登錄按鈕進行提交以后,提交按鈕就會變為灰色,並且給用戶一個友好提示(登錄中...),用戶不能再單擊第二次,直到重新加載頁面或者跳轉。可以發現,我們不需要給這個按鈕恢復到可以再次登錄的狀態,僅僅源於頁面重新進行了加載或者跳轉。
ajax請求
(function($){
$('input').click(function(){
let btn=this;//修改this指向
//表單驗證
...
//ajax異步提交
$.ajax({
url:'',
data:'',
dataType:'',
beforeSend:function(){
//點擊之后讓提交按鈕失效,以實現防止按鈕重復點擊
$(btn).attr('disabled',true);
$(btn).text('登陸中');
},
complete:function(){
//讓按鈕重新有效
$(btn).removeAttr('disabled')
}
success:function(msg){
if(msg==='ok'){
alert('登錄成功')
}else{
alert('登錄失敗')
}
}
}
})
})(jQuery)
請求頻度
let timer=null;
$(input).keyup(function(){
var value=$(this).val();
clearTimeout(timer);
//如果鍵盤敲擊的速度太快,小於100ms就不會向后台發請求,但是最后還是會發送一次請求
timer=setTimeout(function(){
//觸發請求
$.ajax({
url:'',
type:'',
data:value,
success:function(){}
})
},100)
})
總結
從宏觀意義上講,我們需要對每一個按鈕去做“防止重復點擊提交”,,面對這種情況,我們便可以采用一定策略來對其進行封裝實現(如定義通用按鈕類綁定事件)。
從具體情況上來講,我們並不需要對每一個按鈕都去做”防止重復點擊提交“,僅僅需要對某些可能具有復雜后台業務邏輯、或者文件上傳、或者調用其他非本工程接口導致網絡延遲等等情況需要去做”防止重復點擊提交“。與此同時,我們必須要給予用戶友好提示(如文本提示、渲染loading條、顯示文件上傳進度條等等)。兩者需要一起來看、一起來做。當然,我們可以單獨提取狀態顯示這個實現邏輯。代碼如下:
(function($){
var str='';
var dom=$(str).prependTo('body');
$(document).ajaxStart(function(){
dom.stop(true,false).queue(function(
$(this).show().dequeue();
))
});
$(document).ajaxStop(function(){
dom.queue(function(){
$(this).hide().dequeue();
})
})
})(jQuery)