手写节流throttle

节流throttle

应用场景
  • 滚动事件监听scroll:例如监听页面滚动到底部加载更多数据时,使用节流技术减少检查滚动位置的频率,提高性能。
  • 鼠标移动事件mousemove:例如实现一个拖拽功能,使用节流技术减少鼠标移动事件的处理频率。
  • 动画效果:当实现一个基于时间的动画效果时,使用节流技术限制动画帧率,降低计算开销。

它使用了闭包和setTimeout来确保函数fn在指定的delay时间内只被调用一次,即使它被频繁触发。这里是对您代码的一个详细解释:

有很多其他的实现方式....比对时间戳

定时器版
function throttle(fn, delay) {  
  // 创建一个标志位canRun,默认为true,表示函数可以被执行  
  let canRun = true;  
  
  // 返回一个新的函数,这个函数会包裹原来的fn函数  
  return function(...args) {  
    // 如果canRun为false,说明上一次fn的执行还没有完成,直接返回不执行  
    if (!canRun) {  
      return;  
    }  
  
    // 在函数执行前将canRun设为false,表示fn正在执行或等待执行  
    canRun = false;  
  
    // 使用setTimeout来设置一个延时,确保fn在delay时间后执行  
    // 注意:这里的this和args都是从外部函数捕获的,它们代表了原始事件处理函数的上下文和参数  
    setTimeout(() => {  
      // 在delay时间后,执行fn函数,并恢复canRun为true,表示可以再次执行fn  
      fn.apply(this, args);  
      canRun = true;  
    }, delay);  
  };  
}  
  
// 使用示例  
const handleScroll = throttle(function() {  
  console.log('Scroll event handled.');  
}, 200); // 设置节流间隔为200毫秒  
  
window.addEventListener('scroll', handleScroll);

在这个例子中,handleScroll是节流后的函数,它被用作scroll事件的处理程序。无论用户如何频繁地滚动页面,handleScroll函数都只会每200毫秒执行一次,从而有效地减少了不必要的计算和DOM操作,提高了页面的性能。

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Throttle Scroll Event Example</title>  
<style>  
  /* 为了演示,我们可以添加一些样式使页面更长 */  
  body {  
    height: 2000px;  
  }  
</style>  
</head>  
<body>  
<!-- 为了演示,这里添加一些内容使页面更长 -->  
<div style="height: 1000px;">Scroll down to see the throttled scroll event handler in action.</div>  

<script>  
    // 定义节流函数  
    function throttle(fn, delay) {  
      let canRun = true;  
      return function(...args) {  
        if (!canRun) {  
          return;  
        }  
        canRun = false;  
        setTimeout(() => {  
          fn.apply(this, args);  
          canRun = true;  
        }, delay);  
      };  
    }  
      
    // 定义滚动事件处理函数  
    function handleScroll() {  
      console.log('Scroll event handled at', new Date().toISOString());  
      // 这里可以添加实际的滚动处理逻辑,比如加载更多内容、改变样式等  
    }  
      
    // 使用节流函数包装滚动事件处理函数  
    const throttledScrollHandler = throttle(handleScroll, 2000); // 设置节流间隔为200毫秒  
      
    // 添加滚动事件监听器  
    window.addEventListener('scroll', throttledScrollHandler);  
    </script>  
      
</body>  
</html>

演示

补充:

时间戳版
  • 原理:通过比较当前时间和上一次执行函数的时间戳,来判断是否达到指定的时间间隔。
  • 示例代码
function throttle(func, wait) {  
  let previous = 0;  
  return function() {  
    let now = Date.now();  
    let context = this;  
    let args = arguments;  
    if (now - previous > wait) {  
      func.apply(context, args);  
      previous = now;  
    }  
  }  
}  
  
// 使用方法  
content.onmousemove = throttle(count, 1000); // 每1秒执行一次count函数
使用lodash库
  • 示例代码
html复制代码



<script src="./lodash.min.js"></script>  
<script>  
  const box = document.querySelector('.box');  
  let i = 1;  
  function mouseMove() {  
    box.innerHTML = i++; // 如果里面存在大量操作DOM的情况,可能会卡顿  
  }  
  box.addEventListener('mousemove', _.throttle(mouseMove, 500)); // 每500毫秒执行一次mouseMove函数  
</script>

节流防抖的区别

节流throttle指定的delay时间内只被调用一次,即使它被频繁触发;

防抖debounce,只要触发,就重新计算delay;

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向画

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值