# 区别
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
# 应用场景
节流:滚动条监听、搜索框输入
防抖:输入框搜索、窗口大小 resize
# 实现
节流:
- 一定时间内的无论点击多少次,都只会执行第一次,其余的直接 return
1 2 3 4 5 6 7 8 9 10
| function throttled1(fn, delay = 500) { let oldtime = Date.now() return function (...args) { let newtime = Date.now() if (newtime - oldtime >= delay) { fn.apply(null, args) oldtime = Date.now() } } }
|
1 2 3 4 5 6 7 8 9 10 11
| function throttled2(fn, delay = 500) { let timer = null return function (...args) { if (!timer) { timer = setTimeout(() => { fn.apply(this, args) timer = null }, delay); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function throttled(fn, delay) { let timer = null let starttime = Date.now() return function () { let curTime = Date.now() let remaining = delay - (curTime - starttime) let context = this let args = arguments clearTimeout(timer) if (remaining <= 0) { fn.apply(context, args) starttime = Date.now() } else { timer = setTCSSimeout(fn, remaining); } } }
|
防抖:
1 2 3 4 5 6 7 8 9 10 11
| function debounce(func, wait) { let timeout; return function () { let context = this; let args = arguments; clearTimeout(timeout) timeout = setTimeout(function(){ func.apply(context, args) }, wait); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function debounce(func, wait, immediate) { let timeout; return function () { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); if (immediate) { let callNow = !timeout; timeout = setTimeout(function () { timeout = null; }, wait) if (callNow) { func.apply(context, args) } } else { timeout = setTimeout(function () { func.apply(context, args) }, wait); } } }
|