js 防抖和节流
1. 防抖
1.1 概念
当事件被触发时,设定一个周期延迟执行动作,如期间又被触发,则重新设定周期,直到周期结束,才执行动作。
1.2 案例
输入框的keyup事件
下面代码使用定时器对 keyup 事件进行了防抖处理,核心原则就是
- 当用户 500ms 之内没有再次输入,就对文本框的内容进行处理(这里只是简单的输出)
- 如果用户在 500ms 之内继续输入,则清除上次的定时器,自然就不会对文本框内容进行处理了
- 也就是说,最终只会对最后一次输入进行处理
- 试想,如果是实时验证用户名是否可用的需求,做了防抖处理后,能够大大减轻服务器的压力,减 少请求次数
<!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>Document</title>
</head>
<body>
<input type="text" id="int">
<script>
const int = document.querySelector('#int')
int.addEventListener('keyup',debounce(()=>{
console.log(int.value)
}))
function debounce (callback,delay = 500) {
let setTime = null
return function () {
if(setTime) {
clearTimeout(setTime)
}
setTime = setTimeout(()=>{
callback && callback()
setTime = null
},delay)
}
}
</script>
</body>
</html>
2. 节流
2.1 概念
固定周期内,只执行一次动作,若有新事件触发,不执行。周期结束后,又有事件触发,开 始新的周期
2.2 案例
拖拽元素
- 拖拽元素时,要随时拿到被拖拽元素的位置
- 直接用 drag 事件,会频繁触发,很容易导致卡顿
- 节流:无论拖拽速度多快,都会每隔 500ms 触发一次
<!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>Document</title>
<style>
.box {
width: 200px;
height: 150px;
background-color: aqua;
}
</style>
</head>
<body>
<div class="box" draggable="true"></div>
<script>
function fn(e) {
console.log(e)
}
const box = document.querySelector('.box')
box.addEventListener('drag', throtting(fn))
function throtting(callback, delay = 500) {
let setTime = null
return function (e) {
if (setTime) return
setTimeout(() => {
callback && callback(e)
setTime = null
}, delay)
}
}
</script>
</body>
</html>