前端面试题整理——手写防抖和节流
防抖debounce:
防抖是在定义N的时间范围内,如果没有触发事件则执行,如果触发了时间重置进行下一轮判断。
使用场景例如一个输入框有搜索功能,当键盘输入停止了一段时间,判定用户结束或暂停输入,然后再进行接口搜索,避免每次输入都进行一次接口调用。
手写防抖函数:
<input type="text" id="input1" />
<!-- 没有封装的写法 -->
<script>
let input1 = document.getElementById("input1");
let timer = null
input1.addEventListener("keyup", function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
console.log(input1.value);
timer = null
}, 500)
}, false);
</script>
<input type="text" id="input1" />
<script>
// 封装防抖函数
let input1 = document.getElementById("input1");
input1.addEventListener('keyup', debounce(() => {
console.log(input1.value);
}), false)
function debounce(fn, time = 500) {
let timer = null
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, time)
}
}
</script>
节流throttle:
节流是连续触发事件,但是在N的时间里只进行一次触发,避免过度频繁触发事件。
使用场景例如拖拽DIV移动可以间隔一定时间进行移动的触发。
手写节流函数
<style>
#div1 {
border: 1px solid #000;
width: 100px;
height: 100px;
}
</style>
<div id="div1" draggable="true"></div>
<script>
// 不做封装
let div1 = document.getElementById('div1');
let timer = null;
div1.addEventListener('drag', function (e) {
if (timer) return
timer = setTimeout(function () {
console.log(e.offsetX, e.offsetY)
timer = null
}, 100)
}, false)
</script>
<style>
#div1 {
border: 1px solid #000;
width: 100px;
height: 100px;
}
</style>
<div id="div1" draggable="true"></div>
<script>
// 进行封装
let div1 = document.getElementById('div1');
div1.addEventListener('drag', throttle((e) => {
console.log(e.offsetX, e.offsetY)
}), false)
function throttle(fn, time = 100) {
let timer = null;
return function () {
if (timer) return
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, time)
}
}
</script>
放弃安逸,持续努力——成长

浙公网安备 33010602011771号