應用情景
經典使用情景:js的一些事件,比如:onresize、scroll、mousemove、mousehover等;
還比如:手抖、手誤、服務器沒有響應之前的重復點擊;
這些都是沒有意義的,重復的無效的操作,設置對整個系統的影響還可能是致命的,所以我們要對重復點擊的事件進行相應的處理!
節流函數
所謂的節流函數顧名思義,就是某個時刻限制函數的重復調用。
同樣節流函數也是為了解決函數重復提交的問題,而防止重復提交的方法,不止節流函數一種實現。
方法匯總
本文整理了我在工作實踐當中,覺的防止js重復提交,比較好用的方法,在這里和大家分享一下。
一、setTimeout + clearTimeout(節流函數)
本文提供兩種實現方式:普通節流函數和閉包節流函數
二、設定flag/js加鎖
三、通過disable
四、添加浮層比如loading圖層防止多次點擊
具體實現
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div style="width: 200px; height: 100px; background: red;" id="Test">hahaahahhah</div> </body> <script> //------------------------閉包節流函數------------------------ var throttle = function (fn, delay) { var timer = null; return function () { var args = arguments; //參數集合 clearTimeout(timer); timer = setTimeout(function () { fn.apply(this, args); }, delay); } } function postFun(name) { console.log(1) } var t = throttle(postFun, 1000); document.getElementById('Test').onclick = function(){ t(); } //------------------------普通節流函數------------------------ function throttle(fn, delay) { if (fn._id) { clearTimeout(fn._id); } fn._id = window.setTimeout(() => { fn(); fn._id = null; }, delay); } function postFun() { console.log(1) } document.getElementById('Test').onclick = function(){ throttle(postFun, 1000); } //------------------------簡潔節流函數方法------------------------ var timer = null; document.getElementById('Test').onclick = function(){ if(!timer) clearTimeout(timer); timer = setTimeout(function(){ console.log(1) },1000) } //設定flag/js加鎖 var lock = false; jQuery("#submit").on('click', function () { if (lock) { return false; } lock = true; jQuery.post(url, data, function (response) { //TODO:業務代碼 lock = false; }); }); </script> </html>
總結
前兩種方式實現起來比較方便,而后兩種實現起來相對比較繁瑣,如果是為了防止事件的多次觸發,建議使用閉包,如果是表單提交,適度使用后兩種比較穩妥。