應用情景
經典使用情景:js的一些事件,比如:onresize、scroll、mousemove、mousehover等;
還比如:手抖、手誤、伺服器沒有響應之前的重複點選;
這些都是沒有意義的,重複的無效的操作,設定對整個系統的影響還可能是緻命的,是以我們要對重複點選的事件進行相應的處理!
節流函數
所謂的節流函數顧名思義,就是某個時刻限制函數的重複調用。
同樣節流函數也是為了解決函數重複送出的問題,而防止重複送出的方法,不止節流函數一種實作。
方法彙總
本文整理了我在工作實踐當中,覺的防止js重複送出,比較好用的方法,在這裡和大家分享一下。
一、setTimeout + clearTimeout(節流函數)
本文提供兩種實作方式:普通節流函數和閉包節流函數
二、設定flag/js加鎖
三、通過disable
四、添加浮層比如loading圖層防止多次點選
具體實作
方式一:閉包節流函數(可傳遞多個參數)
/**
* 閉包節流函數方法(可傳參數)
* @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);
var lock = false;
jQuery("#submit").on('click', function () {
if (lock) {
return false;
}
lock = true;
jQuery.post(url, data, function (response) {
//TODO:業務代碼
lock = false;
});
});
總結
前兩種方式實作起來比較友善,而後兩種實作起來相對比較繁瑣,如果是為了防止事件的多次觸發,建議使用閉包,如果是表單送出,适度使用後兩種比較穩妥。
關注下面二維碼,訂閱更多精彩内容。
關注公衆号(加好友):
作者:
王磊的部落格
出處:
http://vipstone.cnblogs.com/