javascript 应用之 - 防抖节流

防抖

  • 什么是防抖? 为什么要防抖?

频繁触发 , 只在停下来 n 秒之内无触发后 , 才执行相关操作 ; 因为有些复杂的操作, 如操作DOM , 频繁的触发很影响性能, 可能会把浏览器卡住.

  • 核心

    1. 维护一个定时器, 也就是说对用户的操作 , 做延迟执行
    2. 每次触发都先清除 1 中的定时器, 不管执行了与否 .
  • 简单实现

function debounce(func, waitTime) {
   let timeoutTimer = null;
   return function (...args) {
     clearTimeout(timeoutTimer)
     timeoutTimer = setTimeout(() => func.apply(this, args), waitTime);
   }
 }

// 测试
document.querySelector('#click-test').onclick = debounce(function (...args) {
   console.log(this, args)
 }, 2000);

debounce 函数执行返回一个包装好的函数 , 然后绑定到 click 事件上. 参数 , this 和未包装前保持一致可用.

  • 应用场景
    1. markdown 的实时预览 , 等到停下来输入的时候 , 才会在预览窗口更新内容

节流

  • 什么是节流? 为什么要节流?

频繁触发 , 有个时间轴控制每 n 秒执行一次.

  • 核心

    1. 打点记录法, 首次触发, 立即执行 , 打点为首次触发执行时间点为 o , 然后 n 秒内, 若有触发 , 则 o+n 秒后触发执行一次, 记住新的函数执行触发点, 依此循环; 若在触发执行后的 n 秒内都没有操作 , 则下次触发直接作为原点 o 执行. 回到最开始.
    2. . 第一次触发 , 可以选择直接触发, 最后一次触发, 后续无操作, 也应该可以得到触发.
  • 实现

function throttle(func, interval) {
  let actionPoint = 0; // 函数执行的时间点
  let timeoutTimer = null;
  return function (...args) {
    let now = Date.now()

    // 如果当前触发点的时间 与 上次执行时的时间大于 一个 interval , 则说明连续触发已经中断了, 立马执行
    if (now - actionPoint > interval) {
      func.apply(this, args);
      actionPoint = now; // 记录第一次执行点
    }
    else {
      // 如果还在上次执行之后的 interval 之内, 且未开启定时时 ,以上次执行点为基准算出还有多久执行; 
      if (!timeoutTimer) {
        var leaveTime = interval - (now - actionPoint);
        actionPoint += interval; // 记录下一次执行点
        timeoutTimer = setTimeout(() => {
          func.apply(this, args);
          clearTimeout(timeoutTimer);
          timeoutTimer = null;
        }, leaveTime);
      }
    }
  }
}

// 测试
document.querySelector('#click-test').onclick = throttle(function (...args) {
   console.log(this)
   console.log(args)
   console.log(new Date().getSeconds())
 }, 5000)

基本思路: 首次或者已经间断很久没执行的 , 那么其上一次执行点 , 必然是0 或者相对现在的时间点的距离是大于 interval 的 , 立马让它执行一遍 ; 如果是在距离上次触发点小于 interval , 如果此时有定时器, 就忽略, 没有就开启一个定时器, 延迟执行.

防抖和节流的异同

  • 相似

    1. 都是针对事件频繁触发的优化
  • 差异

    1. 防抖是事件连续触发 , 但仅在事件停止后 n 秒响应一次; 节流是事件持续触发, 但固定间隔 n 秒响应一次.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值