高频事件:触发频率高的事件,如 mousemove scroll keydown input …
给高频事件降频有2个手段:函数防抖,函数节流
函数防抖 - debounce
比如大家非常熟悉的联想查询功能。它是在用户进行键入的同时进行数据请求。但是键盘事件触发的频率是按照字母来计算的,不是按照汉字或者单词,如果每键入一个字母都触发一次数据请求,就非常的低效。在这种情况下,我们就有必要降低操作的频率,保证一定时间内,核心代码只执行一次。
在事件触发时,开始计时,在规定的时间(delay)内,若再次触发事件,将上一次计时(timer)清空,然后重新开始计时。保证只有在规定时间内没有再次触发事件之后,再去执行这个事件。
核心思路:触发事件后再n秒内只执行一次,如果再n秒内又触发了该事件,则重新计算时间。
window.onload = function () {
// 获取元素
const btn = document.querySelector('input')
// 需要防抖的方法
function fn() {
console.log(btn.value)
}
// 做防抖
btn.addEventListener('input', debounce(fn, 1000))
// 防抖方法
function debounce(callback, delay) {
let timer = null // 计时器
return () => { // 闭包返回一个函数
if (timer) { // 如果有计时器就清除计时器˝
clearTimeout(timer)
}
timer = setTimeout(() => { // 重新赋值一个定时器
callback()
}, delay)
}
}
}
个人代码书写思路:
- 定义一个debounce方法接受2个参数一个是需要做防抖的方法,一个是防抖的时间
- debounce方法中定义一个 timer变量用于存放计时器 初始值为0,然后返回一个函数 利用闭包访问这个timer
- 返回的函数中进行判断如果计时器存在就清除计时器,然后再创建一个计时器,计时器中的方法是要防抖的方法,时间是debounce的第二个参数
函数节流 - throttle
在连续触发的事件中,一定的时间内只执行一次我们的函数。
在事件触发之后,开始计时,在规定的时间(delay)内,若再次触发事件,不对此事件做任何处理。保证在规定时间内只执行一次事件.
核心思路:让每次一的函数触发都有一个固定的时间间隔,想要有时间间隔 必须知道上一次的执行时间
window.onload = function () {
// 获取元素
const box = document.querySelector('div')
// 需要节流的方法
let num = 0;
function count() {
console.log(num++)
}
// 做节流
box.addEventListener('mousemove', throttle(count, 500))
// 节流方法
function throttle(callback, delay) {
let prev = 0 // 用于记录上次执行时间
return function () {
let now = Date.now() // 获得当前时间
if (now - prev >= delay) { // 判断时间是否达到预设时间
callback() // 执行回调函数
prev = now; // 更新上次的执行时间
}
}
}
}
个人代码书写思路:
- 定义一个throttle方法接受2个参数一个是需要做节流的方法,一个是节流预设的时间
- throttle方法中定义一个 prev变量用于存上次执行的时间 初始值为0,然后返回一个函数 利用闭包访问这个prev
- 返回的函数中获取当前时间,进行判断当前时间和上次执行时间差是否达到预设时间,如果达到就执行需要执行的方法,然后更新上次执行的时间,将上次执行时间赋值为当前时间