节流、防抖形象记忆,and杂交版节流探秘!

节流

概念简述

在一段时间内只取用第一次的调用。

节流的字面意思就是当一次通行之后到达了阈值,就会开启节流阀门限制你通行。

形象记忆

就像你来到了某个人流量特别大的旅游景点,在一定的时段内,先来的人可以通行,到了人流限制点之后,人员均不得入内,得等待下一波放行时间。

实现原理

节流是借助闭包来实现的,通过闭包来缓存上一次触发回调的时间与当前时间进行比对限制回调执行。

重点

  1. 闭包:返回一个函数,缓存上次调用时间;
  2. 上次调用时间与本次调用时间比对;
  3. 触发传入的回调:使用apply将调用时的this指向回调函数,将arguments传入回调;
js 复制代码
// fn是我们需要包装的事件回调, interval是时间间隔的阈值
function throttle(fn, interval = 200) {
  // last为上一次触发回调的时间
  let last = 0
  // 将throttle处理结果当作函数返回
  return function () {
    // 记录当前调用时间戳
    let now = +new Date()
    // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
    if (now - last >= interval) {
      // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
      last = now;
      // this: 调用时的上下文, arguments 调用时传入的参数
      fn.apply(this, arguments);
    }
  }
}

// 用throttle来包装scroll的回调
const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
document.addEventListener('scroll', better_scroll)

使用场景推荐

  1. 滚动事件处理
  2. 鼠标移动事件
  3. 其他限制请求频率等需要控制函数执行频率的场景

防抖

概念简述

在一段时间内只取用最后一次的调用。

防抖这个概念很形象,防止你手抖误操作,在一段时间还给你改正的机会,会以你最后一次操作为准。

形象记忆

在高考填写志愿的时候,会你足够的时间让你慎重考虑之后填写,在填写期间你可以随意改变志愿,最终会以你最后一版志愿为准。

实现原理

防抖也是借助闭包来实现的,通过闭包来缓存定时器,调用将会被延迟执行,在这个延迟等待过程中如果你重复调用,上次的等待将会中断弃用,开启下一轮延迟执行。

重点

  1. 闭包:返回一个函数,缓存延迟定时器
  2. 回调执行时清除上一个定时器,setTimeout延迟执行本次回调
  3. 触发传入的回调:使用apply将调用时的this指向回调函数,将arguments传入回调
js 复制代码
// fn是我们需要包装的事件回调, delay是每次推迟执行的等待时间
function debounce(fn, delay = 200) {
  // 定时器
  let timer = null
  // 将debounce处理结果当作函数返回
  return function () {
    // 每次事件被触发时,都去清除之前的旧定时器
    timer && clearTimeout(timer)
    // 设立新定时器
    timer = setTimeout(function () {
      // this: 调用时的上下文, arguments 调用时传入的参数
      fn.apply(this, arguments)
    }, delay)
  }
}

// 用debounce来包装scroll的回调
const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)
document.addEventListener('scroll', better_scroll)

使用场景推荐

  1. 输入框搜索
  2. 按钮点击防止重复提交
  3. 其他需要等待用户停止操作后再执行的场景

杂交版节流

不知道大家最近都玩过植物大战僵尸杂交版没有,各种类型的杂交植物把植物大战僵尸又推向了新的高点。咱们也可以推出一个杂交版的节流(或者是杂交版防抖?此文统称为杂交版节流),融合了节流和杂交,妥妥的升级。

只要你弄懂了节流和防抖的原理,相信杂交版的节流你会很熟悉,杂交版的节流就是将防抖的逻辑增添进来了,所以它融合了节流和防抖的优点,在一段时间内,第一次操作将会被执行,如果你在这段时间内有别的操作,将会取最后一次的操作再执行一次,相当于是一个双保险。

js 复制代码
// fn是我们需要包装的事件回调, interval是时间间隔的阈值
function throttlePlus(fn, interval) {
  // last为上一次触发回调的时间, timer是定时器
  let last = 0, timer = null
  // 将throttle处理结果当作函数返回
  return function () { 
    // 记录本次触发回调的时间
    let now = +new Date()
    // 节流
    if (now - last >= interval) {
      // 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应
      last = now
      fn.apply(this, arguments)
    } else {
      // 防抖
      // 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器
      clearTimeout(timer)
      timer = setTimeout(function () {
        last = now
        fn.apply(this, arguments)
      }, interval)
    }
  }
}

// 用新的throttle包装scroll的回调
const better_scroll = throttlePlus(() => console.log('触发了滚动事件'), 1000)
document.addEventListener('scroll', better_scroll)

码上掘金

这是一个点击按钮,按钮的数字会加一的例子,分别使用了节流、防抖、杂交版节流三种方式,让你可以体验一下这三种场景。

相关推荐
孤水寒月3 小时前
基于HTML的悬窗可拖动记事本
前端·css·html
祝余呀3 小时前
html初学者第一天
前端·html
耶啵奶膘6 小时前
uniapp+firstUI——上传视频组件fui-upload-video
前端·javascript·uni-app
视频砖家6 小时前
移动端Html5播放器按钮变小的问题解决方法
前端·javascript·viewport功能
lyj1689977 小时前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
小白变怪兽8 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头8 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
墨菲安全9 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒
GISer_Jing9 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆9 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试