栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

防抖和节流(多种实现&可体验)

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

防抖和节流(多种实现&可体验)

防抖debounce 概念

事件被触发经过单位时间(delay)后再执行回调如果在单位时间内又被触发则重新计时。

防抖函数
const debounce = (cb, delay = 1000) => {
  let timer = null;
  return function (...args) {
    const context = this;
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      cb.apply(context, args);
      timer = null;
    }, delay);
  }
}

若延迟delay设置为1000(默认值)则cb(回调函数)只会在停止触发1s后执行如果一直不断地触发则回调函数始终不执行。

使用

下面是一个简单的使用示例后续介绍的防抖和节流函数的使用方式也是相似的。

const callback = () => {      
  console.log(Math.random());
}
const handle = debounce(callback, 1000);
window.addEventListener('scroll', handle);
防抖函数(第一次触发会立即执行)
const debounceImmediate = (cb, delay = 1000, immediate = true) => {
  let timer = null;
  return function (...args) {
    const context = this;
    const execNow = immediate && !timer;
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      cb.apply(context, args);
      timer = null;
    }, delay);
    execNow && cb.apply(this, args);
  }
}

当设置immediate=true(默认值)、delay=1000(默认值)时第一次触发会立即执行回调函数。后续执行和普通的防抖函数一样只有在停止触发1s后回调函数才会执行如果还是一直不断地触发则回调函数始终不执行。

节流throttle 概念

规定在单位时间(delay)内只能触发一次函数。如果单位时间内多次触发函数只会执行一次回调。

节流函数(使用时间戳)
const throttleUseTimeStamp = (cb, delay = 1000) => {
  let startTime = Date.now();  
 return function(...args) {      
  const context = this;   
  const now = Date.now();    
  if (now - startTime >= delay) {
      cb.apply(context, args);
      startTime = Date.now(); 
  }
 } 
}

若delay=1000则在1s内只会执行一次回调函数。

节流函数的实现(使用定时器)
const throttleUseTimer = (cb, delay) => {
  let timer = null;
  return function(...args) {
    const context = this;
    if (!timer) {
      timer = setTimeout(() => {
 cb.apply(context, args);      
 timer = null;      
      }, delay);  
    } 
  }
}

若delay=1000则在1s内只会执行一次回调函数。

节流函数的实现(第一次触发立即执行最后一次触发也会执行)
const throttleExecMore = function(cb, delay) {
  let timer = null; 
  let startTime = Date.now();
  return function(...args) { 
    const curTime = Date.now(); 
    const remaining = delay - (curTime - startTime); 
    const context = this;    
    timer && clearTimeout(timer);
    if (remaining <= 0) {
      // 第一次触发执行 
      cb.apply(context, args);
      startTime = Date.now();  
    } else {
      // 最后一次触发也会执行      
      timer = setTimeout(() => {
 cb.apply(context, args);
 timer = null;
      }, remaining);   
    }
  }
}

第一次触发会立即执行回调函数最后一次触发也会执行一次回调函数。

亲自体验

将前面介绍的5种防抖和节流函数分别应用在5个输入框的onChange事件的监听上delay值统一设置为1000快速输入1111得到结果如下

完全符合我们前面的分析。

如果不加防抖、节流控制得到结果将是

1
11
111
1111

触发了4次回调函数。

体验防抖和节流 (http://47.92.166.108:3000/blog/index.html#/tutorials/throttle-and-debounce)

体验网址二维码

应用场景举例 防抖
  1. 搜索联想在不断输入值时节约请求资源。
  2. 窗口resize事件
节流
  1. 鼠标不断点击单位时间内只触发一次
  2. 滚动到底部加载更多
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号