防重複提交(前端)
阿新 • • 發佈:2018-11-24
應用情景
經典使用情景:js的一些事件,比如:onresize、scroll、mousemove、mousehover等;
還比如:手抖、手誤、伺服器沒有響應之前的重複點選;
這些都是沒有意義的,重複的無效的操作,設定對整個系統的影響還可能是致命的,所以我們要對重複點選的事件進行相應的處理!
節流函式
所謂的節流函式顧名思義,就是某個時刻限制函式的重複呼叫。
同樣節流函式也是為了解決函式重複提交的問題,而防止重複提交的方法,不止節流函式一種實現。
方法彙總
本文整理了我在工作實踐當中,覺的防止js重複提交,比較好用的方法,在這裡和大家分享一下。
一、setTimeout + clearTimeout(節流函式)
本文提供兩種實現方式:普通節流函式和閉包節流函式
二、設定flag/js加鎖
三、通過disable
四、新增浮層比如loading圖層防止多次點選
具體實現
一、setTimeout + clearTimeout(節流函式)
方式一:閉包節流函式(可傳遞多個引數)
/** * 閉包節流函式方法(可傳引數) * @param Function fn 延時呼叫函式 * @param Number delay 延遲多長時間 * @return Function 延遲執行的方法 */ var throttle = function (fn, delay) { var timer = null; return function () { var args = arguments; //引數集合 clearTimeout(timer); timer = setTimeout(function () { fn.apply(this, args); }, delay); } } /** * 要執行的方法 * @param String name 傳遞的引數 */ function postFun(name) { document.writeln("名字:" + name); } //================測試部分 => 【1s重複點選10次】 var t = throttle(postFun, 1000); var ejector = setInterval(() => { t("tiger"); }, 100); setTimeout(() => { clearInterval(ejector); }, 1000);
執行結果:
方式二:普通節流函式方法
/** * 普通節流函式方法 * @param Function fn 延時呼叫函式 * @param Number delay 延遲多長時間 */ function throttle(fn, delay) { if (fn._id) { clearTimeout(fn._id); } fn._id = window.setTimeout(() => { fn(); fn._id = null; }, delay); } /** * 要執行的方法 */ function postFun() { document.writeln(new Date().getTime()); } //================測試部分 => 【1s重複點選10次】 var interval = setInterval(() => { throttle(postFun, 1000); }, 100); setTimeout(() => { clearInterval(interval); }, 1000);
執行結果:
二、設定flag/js加鎖
var lock = false; jQuery("#submit").on('click', function () { if (lock) { return false; } jQuery.post(url, data, function (response) { //TODO:業務程式碼 lock = false; }); });
總結
前兩種方式實現起來比較方便,而後兩種實現起來相對比較繁瑣,如果是為了防止事件的多次觸發,建議使用閉包,如果是表單提交,適度使用後兩種比較穩妥。