浅谈JavaScript节流和防抖函数
前言
在前端开发中,我们经常会遇到需要监听用户操作并执行相应任务的情况,例如用户在搜索框中输入关键词时,会实时通过ajax请求获取匹配结果;用户在滚动页面时,会自动加载更多的内容等等。但是由于用户的操作往往不可预测,当用户频繁进行操作时,会导致一些性能问题,如频繁地发送请求,重复执行相同的逻辑等等。这时候,就需要用到节流和防抖函数来限制这种不必要的操作。
节流函数(throttle)
节流函数是指在一段时间内,只执行一次事件。它可以避免一些高频率调用的事件,使其被间隔执行。常见的节流函数有时间戳版本和定时器版本。时间戳版本即指在固定时间内执行一次时间函数,而定时器版本则是在固定时间后执行一次事件。
以定时器版本为例,其基本模板代码为:
function throttle(func, delay) {
let canRun = true;
return function() {
if (!canRun) return;
canRun = false;
setTimeout(() => {
func.call(this, ...arguments);
canRun = true;
}, delay);
};
}
在上述代码中,canRun
表示此时函数能否执行的标志,在未达到规定时间时,其为false
,在达到规定时间后,其变为true
,以便下一次可以执行函数。在函数执行前将canRun
标记为false
,并将当次执行函数的参数延迟到delay后才执行。 这才是节流执行的精髓所在。
接下来,我们来看一个实例,通过点击一次按钮打印当前时间,并且确保在一定时间间隔内只执行一次。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>throttle示例</title>
</head>
<body>
<button id="btn">点击弹出当前时间</button>
<script>
function throttle(func, delay) {
let canRun = true;
return function () {
if (!canRun) return;
canRun = false;
setTimeout(() => {
func.call(this, ...arguments);
canRun = true;
}, delay);
};
}
let clickHandler = throttle(function () {
console.log(new Date().toLocaleTimeString());
}, 1000);
document.getElementById('btn').addEventListener('click', clickHandler);
</script>
</body>
</html>
在上述示例中,当我们点击按钮后,函数会在1秒后输出当前时间,即使我们快速点击多次,也只会在1秒后输出最后一次操作的时间。
防抖函数(debounce)
防抖函数也是用于避免函数的重复执行,但是相比节流函数,它是在每次事件结束后规定时间再执行事件,而不是固定时间内只执行一次事件。这样,在函数执行后,如果用户继续操作,则计时器被清空,重新规定事件。
以定时器版本为例,其基本模板代码为:
function debounce(func, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.call(this,...arguments);
},delay);
};
}
在上述代码中,timer
表示setTimeout函数的返回值,在每次函数执行前清除上次setTimeout事件,调用最新的setTimeout事件来执行新的函数。调用方法如下:
let debouncedFunc = debounce(function () {
console.log(new Date().toLocaleTimeString());
}, 1000);
接下来,我们来看一个实例,限制滚动事件每500ms触发一次:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>debounce示例</title>
</head>
<body>
<div style="height: 2000px"></div>
<script>
function debounce(func, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.call(this, ...arguments);
}, delay);
};
}
window.onscroll = debounce(function () {
console.log(new Date().toLocaleTimeString());
}, 500);
</script>
</body>
</html>
在上述示例中,当我们滚动页面时,函数会在500毫秒后输出当前时间,如果在500ms内连续滚动,只会在最后一次滚动结束后500ms输出时间。
总结
节流和防抖函数虽然在代码结构上十分相似,但是还是有一些区别的。防抖函数是在一定时间后执行事件,进行了时间避免错误,而节流函数则是规定在特定时间内只执行一次事件。在实际开发中,需要根据具体情况选择节流函数或防抖函数进行优化,从而减少对性能的影响。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈JavaScript节流和防抖函数 - Python技术站