防抖(debounce)

原理

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

实现方式

每次触发事件时设置一个延迟调用的方法,并且取消前一次的延迟调用方法。

  1. //防抖函数
  2. function debounce(fn) {
  3. let timer = null;
  4. return function () {
  5. if (timer) clearTimeout(timer);
  6. timer = setTimeout(function () {
  7. fn(...arguments)
  8. }, 500)
  9. }
  10. }
  11. //事件处理函数
  12. function fn(e) {
  13. console.log(this.name);//'防抖'
  14. console.log(document.documentElement.scrollTop)
  15. }
  16. //验证this指向
  17. let obj = {
  18. fn,
  19. name: '防抖'
  20. }
  21. window.addEventListener('scroll', debounce(obj.fn.bind(obj)));//用bind方法绑定this

缺点

如果事件在规定时间内被不断的触发,则这个方法会被不断的延迟

应用场景

  • search搜索框,用户不断输入值时,用防抖来节约请求资源。
  • window触发resize,scroll等事件时,会不断触发,用防抖来让他只执行一次。

节流(throttle)

原理

触发高频事件后,n秒内只执行一次,所以节流会稀释函数的执行频率。

实现方式

每次触发事件时,如果当前有等待执行的延迟函数,则直接return。

  1. /** 节流 */
  2. function throttle(fn){
  3. let canRun = true;
  4. return function(){
  5. if(!canRun) return;
  6. canRun = false;
  7. setTimeout(function(){
  8. fn(...arguments);
  9. canRun = true;
  10. },500);
  11. }
  12. }
  13. function fn(){
  14. console.log(document.documentElement.scrollTop);
  15. }
  16. window.addEventListener('scroll', throttle(fn))

应用场景

  • 鼠标不断点击触发,mousedown单位时间内只触发一次。
  • 监听滚动事件,比如是否划到底部自动加载更多,用节流来判断。