1,防抖和节流是什么有什么区别
| 标题 | 防抖 | 节流 |
|---|---|---|
| 定义 | 防止事件一直高频率触发, 在高频率触发时选择只执行最后一次 | 防止事件一直高频率触发, 在高频率触发时限制按照固定频率执行 |
| 使用场景 | 监听输出框触发事件 改成光标离开输出框时触发 | window.scroll |
| 核心区别 | 清除定时器clearTimeout(timer); | 判断触发频率是否高于当前设置的wait |
2,简单实现写防抖节流方法
2.1 频繁点击btn按钮,添加防抖功能,频率超过200s时只执行一次
==>默认事件
btn.onclick = function(){
console.log("触发点击事件");
}
==>加上防抖功能
let timer;
btn.onclick = function(){
clearTimeout(timer);
timer = setTimeout(()=>{
console.log("触发点击事件");
},200)
}
==>简单封装
const debounce = function debounce(func,wait){
let timer=null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=>{
func.call(this) //console.log("触发点击事件");
},wait)
}
}
function f(){
console.log("触发点击事件");
}
btn.onclick = debounce(f,200);
2.2 给屏幕滚动时间添加限流
==>原始方法
window.onscroll = function(){
console.log("屏幕滚动");
}
==>加上节流功能
let timer = null;
window.onscroll = function(){
let flag = true;//首次触发可以调用
if(flag){
flag = false;//一旦触发就立刻限制触发
clearTimeout(timer);//清空定时器
timer = setTimeout(()=>{
console.log("屏幕滚动");
flag = true;//执行后解除限制
},200)
}
}
==>简单封装节流功能
const throttle = function throttle(func,wait){
let timer = null
return function(){
let flag = true;
if(flag){
flag = false;
clearTimeout(timer);
timer = setTimeout(()=>{
func.call(this);
},wait)
}
}
}
function fn(){
console.log("屏幕滚动");
}
window.onscroll = throttle(fn,200);
3,高级封装 封装一个util组件
(function(){
const clearTimer = function clearTimer(timer){
if(timer!=null){
clearTimeout(timer);
}
return null;
}
/**
* 防抖
* @param {Function} func
* @param {Number} wait
* @param {Boolean} immediate
* @returns function
*/
const debounce = function debounce(func,wait,immediate){
//init param
if(typeof func!=='function') throw TypeError('func is not a function');
if(typeof wait ==='boolean') immediate = wait;
wait = +wait;
if (isNaN(wait)) wait=300;
if(typeof immediate!=='boolean') immediate =false;
//handler
let timer = null;
return function operate(...params){
let now = !timer && immediate;//是否立即执行
timer = clearTimer(timer);//清空timer
timer = setTimeout(()=>{
if(!immediate) func.call(this,...params);
timer = clearTimer(timer);
},wait)
if(now) { console.log(now);func.call(this,...params);}
}
}
/**
* 节流
* @param {Function} func
* @param {Number} wait
* @returns function
*/
const throttle = function throttle(func,wait){
//init parm
if(typeof func !== 'function') throw TypeError('func is not a function')
wait = +wait;
if(isNaN(wait)) wait =300;
let timer=null, preDate = 0;
//handler
return function operate(...param){
let now = +new Date(),
diff = wait - (now - preDate);
if(diff<=0){//触发频率低于wait,就是正常操作立即执行即可
func.call(this,...param);
preDate = +new Date();
}else if(!timer){//触发频率高于wait,设置限流
clearTimer(timer)
timer = setTimeout(()=>{
func.call(this,...param);
preDate = +new Date();
},diff)
}
}
}
const utils = {
debounce,
throttle
}
window.utils =_UT = utils
})()