节流函数(throttle)就是让事件处理函数(handler)在规定的时间之内只执行一次。比如在秒杀商品时,用户会高频的点击抢购按钮,避免系统出现问题,可以使用节流限制用户在规定的时间内只能执行一次。用户可以高评率的点击抢购按钮,但程序只在规定的事件之内处理一次。节流函数可以用立即执行(时间戳)和延迟执行(定时器)两种方式进行处理。
每次触发事件,都在规定时间开始执行。
函数的实现
function throttle(fn, delay) {
var delay = delay || 1000;
var prevDate = new Date();
var prev = prevDate.getTime();
return function (args) {
var nowDate = new Date();
var now = nowDate.getTime();
if (now - prev >= delay) {
fn.call(this, args);
prev = now;
}
};
}
时间戳节流函数完整demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>时间戳节流函数</title>
</head>
<body>
<div>立即执行的节流函数</div>
<div
id="handler"
style="width: 500px; height: 200px; border: 5px solid #f2f2f2"
>
点击我
</div>
<script>
//节流函数
function throttle(fn, delay) {
var delay = delay || 1000;
var prevDate = new Date();
var prev = prevDate.getTime();
return function (args) {
var nowDate = new Date();
var now = nowDate.getTime();
if (now - prev >= delay) {
fn.call(this, args);
prev = now;
}
};
}
//执行事件
var count = 0;
document.getElementById("handler").onclick = throttle(function () {
this.innerHTML = "点击我:" + count;
count++;
}, 1000);
</script>
</body>
</html>
每次触发事件,都在规定的时间结束之后执行。
函数的实现
function throttle(fn, delay) {
var delay = delay || 1000;
var timer = null;
return function (args) {
var context = this;
if (!timer) {
timer = setTimeout(function () {
fn.call(context, args);
timer = null;
}, delay);
}
};
}
定时器节流函数完整demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>定时器节流函数</title>
</head>
<body>
<div>延迟执行的定时器节流函数:</div>
<div
id="handler"
style="width: 500px; height: 200px; border: 5px solid #f2f2f2"
>
点击我
</div>
<script>
// 节流函数
function throttle(fn, delay) {
var delay = delay || 1000;
var timer = null;
return function (args) {
var context = this;
if (!timer) {
timer = setTimeout(function () {
fn.call(context, args);
timer = null;
}, delay);
}
};
}
//执行事件
var count = 0;
document.getElementById("handler").onclick = throttle(function () {
this.innerHTML = "点击我:" + count;
count++;
}, 1000);
</script>
</body>
</html>
语法
throttle(fn, delay = 1000, immediate = true)
函数的实现
function throttle(fn, delay, immediate) {
// 延迟时间
var delay = delay || 1000;
//及时执行
var immediate = immediate ? immediate : true;
// 定时器存储器
var timer = null;
//启动时间
var defaultTime = +new Date();
return function (args) {
var context = this;
if (immediate) {
var now = +new Date();
if (now - defaultTime >= delay) {
fn.call(context, args);
defaultTime = now;
}
} else {
if (!timer) {
timer = setTimeout(function () {
fn.call(context, args);
timer = null;
}, delay);
}
}
context = timer = null;
};
}
节流函数封装 demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>节流函数封装</title>
</head>
<body>
<div>节流函数封装,立即执行和延迟执行</div>
<div
id="handler"
style="width: 500px; height: 200px; border: 5px solid #f2f2f2"
>
点击我
</div>
<script>
// 节流函数
function throttle(fn, delay, immediate) {
// 延迟时间
var delay = delay || 1000;
//及时执行
var immediate = immediate ? immediate : true;
// 定时器存储器
var timer = null;
//启动时间
var defaultTime = +new Date();
return function (args) {
var context = this;
if (immediate) {
var now = +new Date();
if (now - defaultTime >= delay) {
fn.call(context, args);
defaultTime = now;
}
} else {
if (!timer) {
timer = setTimeout(function () {
fn.call(context, args);
timer = null;
}, delay);
}
}
context = timer = null;
};
}
//执行事件
var count = 0;
document.getElementById("handler").onclick = throttle(
function () {
this.innerHTML = "点击我:" + count;
count++;
},
3000,
false
);
</script>
</body>
</html>
源代码已上传的gitee,可以直接下载后运行。
https://gitee.com/usuing/lession/tree/master/节流函数