防抖
在前端开发中,有些事件会持续触发,如scroll,resize事件,如果不停地执行处理函数,则会大大地消耗浏览器性能。这时就需要防抖函数来减少执行函数的频率。
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖函数的原理是:设定一个延时器,在n秒内多次触发事件并不执行函数,而是在每次触发后都重置延时器,将函数延后执行,只有当n秒内不再触发事件,函数才会执行。以scroll事件为例,当我们滚动页面时,会不停地触发scroll事件,但每次触发事件,并不执行函数,而是重置延时器,只有当1秒内不触发事件才会执行函数
实现:
function debounce(fn,timeout){
//存储延时器
let timer
return function (){
if(timer!==null){
//防抖函数的代码使用这两行代码来获取 this 和 参数,是为了让 debounce 函数最终返回的函数 this 指向不变以及依旧能接受到 e 参数。
let context = this
let args = arguments
//当再次触发事件时,如果有延时器存在,就清除当前延时器
clearTimeout(timer)
//重置延时器,即再延迟调用事件处理函数,只有当timeout时间内不再触发事件,才会执行函数
timer = setTimeout(()=>{
//使得this不变
fn.apply(context,args)
}, timeout);
}
}
}
function handle(){
console.log(Math.random())
}
window.onscroll=debounce(handle,1000)
节流
类似于防抖,节流是在一段时间内只允许函数执行一次,实现方法可以是时间戳法和定时器法。
实现:
//时间戳
/* 1.先记录第一次触发事件的时间prev,
2.当第二次触发事件时,记录时间now,
3.判断两次时间间隔是否大于设定的时间,如果小于就不执行函数,等待下一次触发事件,如果大于就执行函数,并将时间轴后移,即把prev的值改为当前时间
4.回到第一步反复执行
特点:第一次触发事件不执行函数,之后不管触发多少次事件,每n秒执行一次函数,最后一次触发事件不会执行*/
function throttle(fn,wait){
let prev = Date.now()
return function (){
let context = this
let args = arguments
let now = Date.now()
if(now-prev>=wait){
fn.apply(context,args)
prev = Date.now()
}
}
}
function handle(){
console.log(Math.random())
}
let ipt = document.getElementById('ipt')
ipt.oninput=throttle(handle,3000)
//定时器
/*
1. 第一次触发事件,设置延时器延时n秒执行函数
2.第二次触发事件,如果原延时器存在,则不执行函数,等待延时器,如果不存在,则设置延时器延时n秒执行函数
3.延时器到时间执行函数,并重置延时器为null
4.重复第一步
特点:第一次触发事件会延时n秒执行函数,最后一次触发事件也会延时n秒执行函数*/
function throttle1(fn,wait){
let timer = null
return function (){
let context = this
let args = arguments
if(!timer){
timer = setTimeout(() => {
fn.apply(context,args)
timer = null
}, wait);
}
}
}
let ipt2 = document.getElementById('ipt2')
ipt2.oninput=throttle1(handle,3000)
网友评论