区别
- 函数防抖,指的是事件触发n秒后再执行回调,如果在n秒期间又被触发,则重新计时
- 函数节流, 指的是事件触发n秒后再执行回调,再n秒内又被触发,不会执行, 在n秒内触发无效(可以理解为在这n秒内只能执行一次)
需要用到的防抖或者节流的情况
防抖应用场景
-
鼠标:mousemove,mouseover,input输入框的keypress
-
验证规则:手机号码,邮箱验证
-
浏览器:resize
节流应用场景 -
鼠标:mousemove,mouseover
-
搜索框的联想功能
-
滚动加载scroll
-
高频率提交,表单重复提交
简单的防抖
var timer //存放setTimeout函数防止函数执行完被销毁
var num = 0
let div = document.getElementById("debounce")
function debounce(fn, delay){
clearTimeout (timer)
timer = setTimeout(function(){
fn()
},delay)
}
function debounceTest(){
div.innerHTML = num++
}
div.onmousemove = ()=>{
debounce(debounceTest,1000)
}
优化后的防抖
由于在实际开发中,我们不可能用一个全局变量来存放的,所以我们应该用闭包来解决问题
var num = 0
let div = document.getElementById("debounce")
function debounce(fn, delay){
let timer
return function(){
let _this = this
let args = arguments
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
fn.apply(_this, args)
}, delay)
};
}
function debounceTest() {
div.innerHTML = num++
}
div.onmousemove = debounce(debounceTest,1000)
节流
var num = 0
let div = document.getElementById("debounce")
function throttle(fn, delay){
let timer
return function(){
let _this = this
let args = arguments
if(timer){
return //触发事件,如果有timer存在就跳过,不执行该次函数,必须等timer为空了才会去执行,所以在delay时间内,只能执行一次
}
timer = setTimeout(()=>{
fn.apply(_this, args)
timer = null //执行完之后就置空
}, delay)
};
}
function throttleTest() {
div.innerHTML = num++
}
div.onmousemove = throttle(throttleTest,1000)
利用时间戳实现节流
原理是比较上一次触发的事件时间与这一次触发事件的事件的差值跟预定的时间间隔比较
var num = 0
let div = document.getElementById("debounce")
function throttle(fn, delay){
let previous = 0
return function(){
let _this = this
let args = arguments
let now = new Date()
if(now - previous > delay){
fn.apply(_this, args)
previous = now
}
};
}
function throttleTest() {
div.innerHTML = num++
}
div.onmousemove = throttle(throttleTest,1000)