函数防抖
原理
触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。简单的说,当一个动作连续触发,则只执行最后一次
应用场景
- 搜索功能实现
- 手机号码验证和邮箱验证
- 窗口大小Resize,只需窗口调整完成后,计算窗口大小,防止重复渲染
<body>
<input type="text" id="inp">
<script>
var input = document.getElementById("inp")
inp.oninput = function () {
debounce(ajax)
}
function debounce(fn) {
var timeout = null
return function () {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(function () {
fn()
}, 1000)
}
}
function ajax() {
console.log('ajax发送的数据为: ' + input.value)
}
</script>
</body>
函数节流
原理
触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用
应用场景
- 高频点击提交,表单重复提交
- 上拉加载,加载更多或滚到底部监听
// 定时器版
<script>
var canRun = true
document.onscroll = function(){
if(!canRun){
// 判断是否已空闲,如果在执行中,则直接return
return
}
canRun = false
setTimeout(function(){
console.log("函数节流")
canRun = true
}, 300)
}
</script>
// 时间戳版
<script>
let startTime = Date.now() // 开始时间
let time = 500 // 间隔时间
let timer
window.onscroll = function throttle(){
let currentTime = Date.now()
if(currentTime - startTime >= time){
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
console.log('滚动条位置:' + scrollTop)
startTime = currentTime
}else{
clearTimeout(timer)
timer = setTimeout(function () {
throttle()
}, 50)
}
}
</script>
函数防抖和函数节流的区别
相同点
- 都可以通过使用 setTimeout 实现
- 降低回调执行频率,节省计算资源
不同点
- 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
- 函数防抖关注一定时间连续触发,只在最后执行一次,而函数节流侧重于一段时间内只执行一次