js 防抖和节流 (学习笔记)
/** * @desc 函数节流 (牛逼版本) * @param func 函数 * @param wait 延迟执行毫秒数 * @param type 1 表时间戳版,2 表定时器版 */ function throttle(func, wait ,type) { if(type===1){ let previous = 0; }else if(type===2){ let timeout; } return function() { let context = this; let args = arguments; if(type===1){ let now = Date.now(); if (now - previous > wait) { func.apply(context, args); previous = now; } }else if(type===2){ if (!timeout) { timeout = setTimeout(() => { timeout = null; func.apply(context, args) }, wait) } } } }
/** * @desc 函数防抖 (牛逼版本) * @param func 函数 * @param wait 延迟执行毫秒数 * @param immediate true 表立即执行,false 表非立即执行
* @param 防抖只会在事件结束后执行一次处理函数 immediate则用来判断是否直接执行处理函数(func.apply()) 或 延迟执行(setTimeout(()=>{func.apply()},args)) */ function debounce(func,wait,immediate) { let timeout; return function () { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout; timeout = setTimeout(() => { timeout = null; }, wait) if (callNow) func.apply(context, args) } else { timeout = setTimeout(function(){ func.apply(context, args) }, wait); } } }
// 节流 (简易版): 解释:节流 在事件触发后会执行N次 间隔对应的时间就会执行一次
例子:设置对应时间为1 则事件触发后每一秒执行一次处理函数 var throttle = function(func, delay) { var timer = nullvar startTime = Date.now()//获取第一次当前时间戳
return function() { var curTime = Date.now() // 获取执行时的时间戳 var remaining = delay - (curTime - startTime)// 获取时间差 并获取是否到达触发的间隔时间 var context = this; var args = arguments; clearTimeout(timer); if (remaining <= 0) {// 判断是否到达触发时间 (设置的触发间隔时间)小于(当前触发于上次间隔时间) 当remaining小于0时 触发处理函数 并重新定义第一次时间戳 func.apply(context, args); startTime = Date.now(); } else { timer = setTimeout(func, remaining)// 注册定时器 } } } function handle() { console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000))
// 防抖(简易版) 解释:事件触发结束后才会执行一次处理函数 触发跟触发时不会进入处理函数 function antiShake(fn, delay = 300) { var timer = null return function () { if (timer !== null) { clearTimeout(timer) } timer = setTimeout(fn, delay) } } // 处理函数 function fun() { console.log('0') } // 滚动事件 window.addEventListener('scroll',antiShake(fun, 1000))
例子:
防抖使用场景 监听input事件输入事件 触发请求 不能每次输入都请求 浪费资源并会造成卡顿 这个时候防抖最合适
节流使用场景 监听滚动事件 选择地址栏 滚动到对应的城市 选中对应城市的字母 不能等待事件结束再去触发处理函数 则使用节流 短时间去触发处理函数 这个时候节流最合适