防抖与节流详解以及实战案例

防抖(Debouncing)与节流(Throttling)详解及实战案例

在前端开发中,处理高频事件(如窗口大小调整、滚动、键盘输入等)时,为了提高性能并减少不必要的计算或DOM操作,常常采用防抖(Debouncing)和节流(Throttling)两种技术。这两种技术虽然目的相似,但实现方式和应用场景有所不同。

防抖和节流的定义

  • 防抖(Debouncing):确保事件处理函数在指定时间间隔内只执行一次。如果在这个时间间隔内事件被再次触发,则重新计时。防抖常用于输入框搜索自动完成、窗口大小调整等场景。即,单位时间内,频繁触发事件,只执行最后一次。

  • 节流(Throttling):确保事件处理函数在指定时间间隔内至少执行一次。如果事件在这个时间间隔内被多次触发,则只有第一次或最后一次会被执行。节流常用于滚动事件监听、动画循环等场景。即,单位时间内,频繁触发事件,只执行一次。

防抖使用流程

核心是利用 setTimeout定时器来实现

  1. 声明定时器变量

  2. 每次鼠标移动(事件触发)的时候都要先判断是否有定时器,如果有先清除以前的定时器

  3. 如果没有定时器,则开启定时器,存入到定时器变量里面

  4. 定时器里面写函数调用

防抖函数的实现

function debounce(func, wait) {  
  let timeout;  
  return function() {  
    const context = this;  
    const args = arguments;  
    clearTimeout(timeout); // 清除之前的定时器  
    timeout = setTimeout(() => {  
      func.apply(context, args); // 使用apply保持this上下文和参数传递  
    }, wait);  
  };  
}

使用案例

//html部分
<button id="myButton">点击我,但别太频繁!</button>  
<div id="result"></div>

//javascript部分
function doSomething() {  
  const resultDiv = document.getElementById('result');  
  resultDiv.textContent = '按钮被点击了(防抖生效)!';  
}  
  
// 获取按钮并添加点击事件监听器,使用防抖函数  
const button = document.getElementById('myButton');  
const debouncedClick = debounce(doSomething, 500); // 设置防抖时间为500毫秒  
button.addEventListener('click', debouncedClick);

在这个例子中,当用户频繁点击按钮时,doSomething 函数不会立即执行。只有当用户在最后一次点击后等待了500毫秒没有再次点击时,doSomething 函数才会执行,更新页面上的文本内容。这样,即使用户快速连续点击按钮,页面上显示的文本也不会频繁地更新,从而达到了防抖的效果。

节流使用流程

核心是利用定时器(setTimeout)来实现

  1. 声明一个定时器变量

  2. 当鼠标每次滑动都先判断是否有定时器了,如果有定时器则不开启新定时器

  3. 如果没有定时器则开启定时器,记得存到变量里面

  4. 定时器里面调用执行的函数

  5. 定时器里面要把定时器清空

节流函数的实现

function throttle(func, limit) {  
  let lastFunc;  
  let lastRan;  
  return function() {  
    const context = this;  
    const args = arguments;  
    if (!lastRan) {  
      func.apply(context, args);  
      lastRan = Date.now();  
    } else {  
      clearTimeout(lastFunc);  
      lastFunc = setTimeout(function() {  
        if ((Date.now() - lastRan) >= limit) {  
          func.apply(context, args);  
          lastRan = Date.now();  
        }  
      }, limit - (Date.now() - lastRan));  
    }  
  };  
}

使用案列

// 假设的操作函数  
function handleScroll() {  
  console.log('滚动事件被处理了(节流生效)!', new Date().toLocaleTimeString());  
}  
  
// 使用节流函数包装handleScroll  
const throttledScroll = throttle(handleScroll, 500);  
  
// 添加滚动事件监听器,并使用节流函数  
window.addEventListener('scroll', throttledScroll);

在这个例子中,当用户滚动页面时,handleScroll 函数不会立即执行。相反,它会在每次滚动事件触发时检查距离上次执行的时间是否已经超过500毫秒。如果是,则执行该函数;如果不是,则等待直到满足条件再执行。这样,即使在用户快速滚动页面时,handleScroll 函数也不会被过度调用,从而实现了节流的效果。

使用lodash来解决防抖和节流案列:

案例一:输入框防抖

场景:用户在搜索框输入时,不希望每次按键都触发搜索请求,而是等待用户停止输入一段时间后再进行搜索。

代码示例(使用lodash):

import _ from 'lodash';

const search = _.debounce(function(query) {
    console.log('Searching for:', query);
    // 这里可以放置搜索请求的代码
}, 300);

// 绑定到输入框的input事件
document.querySelector('#searchBox').addEventListener('input', function(e) {
    search(e.target.value);
});

案例二:滚动节流

场景:在滚动事件中,不需要每次滚动都执行某些操作(如计算可视区域元素),而是希望在滚动过程中定期执行。

代码示例(使用lodash):

import _ from 'lodash';

const throttledScrollHandler = _.throttle(function() {
    console.log('Scroll event handler called');
    // 可以在这里执行一些操作,如计算可视区域内的元素
}, 1000);

window.addEventListener('scroll', throttledScrollHandler);

使用场景

  • 防抖(Debouncing)

    • 搜索框输入时减少请求次数。
    • 窗口大小调整时延迟执行重排或重绘相关的代码。
    • 按钮点击后,防止因双击而重复执行。
  • 节流(Throttling)

    • 滚动事件监听,减少滚动过程中的计算量。
    • 游戏中的动画循环,控制更新频率。
    • 实时搜索结果的展示,控制请求频率。

Lodash是一个一致性、模块化、高性能的JavaScript实用工具库。它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,通过降低这些常见数据类型的使用难度,从而让JavaScript编程变得更加简单和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值