在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
对于函数防抖,有以下几种应用场景:
- 给按钮加函数防抖防止表单多次提交。
- 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
- 判断
scroll
是否滑到底部,滚动事件
+函数防抖
总的来说,适合多次事件一次响应的情况
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script>
function testDebounce() {
console.log('test');
}
document.onmousemove = () => {
testDebounce();
}
script>
body>
html>
var timer; // 维护同一个timer
function debounce(fn, delay) {
clearTimeout(timer);
timer = setTimeout(function(){
fn();
}, delay);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script>
var timer; // 维护同一个timer
function debounce(fn, delay) {
clearTimeout(timer);
timer = setTimeout(function(){
fn();
}, delay);
}
// test
function testDebounce() {
console.log('test');
}
document.onmousemove = () => {
// testDebounce();
debounce(testDebounce, 1000);
}
script>
body>
html>
上面例子中的debounce就是防抖函数,在document中鼠标移动的时候,会在onmousemove最后触发的1s后执行回调函数testDebounce;如果我们一直在浏览器中移动鼠标(比如10s),会发现会在10 + 1s后才会执行testDebounce函数(因为clearTimeout(timer)),这个就是函数防抖。
可以看到大大减小了onmousemove事件的调用次数。
防抖函数优化进阶:
function debounce(fn, delay) {
let timer = null;
return function(...args) {
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
function debounce(fn, delay) {
let timer = null;
return function(...args) {
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
// test
function testDebounce(e, content) {
console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // 防抖函数
document.onmousemove = function (e) {
testDebounceFn(e, 'debounce'); // 给防抖函数传参
}
每隔一段时间,只执行一次函数。
对于函数节流,有如下几个场景:
- 游戏中的刷新率
- DOM元素拖拽
- Canvas画笔功能
总的来说,适合大量事件按时间做平均分配触发。
function throttle(fn, gapTime) {
let _lastTime = null;
return function () {
let _nowTime = + new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn();
_lastTime = _nowTime
}
}
}
let fn = ()=>{
console.log('boom')
}
setInterval(throttle(fn,1000),10)
结果是一秒打出一次boom
相同点:
不同点: