防抖和节流(较全&可体验)

防抖(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. 滚动到底部加载更多

原文地址:https://www.cnblogs.com/fe-read/p/11783557.html

时间: 2024-10-30 07:05:26

防抖和节流(较全&可体验)的相关文章

函数防抖与节流

1.为什么会有函数的防抖与节流及使用场景 在进行窗口的resize.scroll,输入框内容校验或者向后端发起ajax等操作时, 如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕. 此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果. 2.函数防抖与函数节流的概念及实现原理 函数防抖(debounce): 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了

前端进击的巨人(八):浅谈函数防抖与节流

本篇课题,或许早已是烂大街的解读文章.不过春招系列面试下来,不少伙伴们还是似懂非懂地栽倒在(-面试官-)深意的笑容之下,权当温故知新. JavaScript的执行过程,是基于栈来进行的.复杂的程序代码被封装到函数中,程序执行时,函数不断被推入执行栈中.所以 "执行栈" 也称 "函数执行栈". 函数中封装的代码块,一般都有相对复杂的逻辑处理(计算/判断),例如函数中可能会涉及到 DOM 的渲染更新,复杂的计算与验证, Ajax 数据请求等等. 前端页面的操作权,大部分

JS的防抖和节流

数个月之前,在一次前端的性能优化中,接触到了JS中防抖和节流,一开始还不明白他们的应用在哪里,可后来才知道,这是前端中最基础的性能优化,在绑定 scroll .resize 这类事件时,当它发生时,它被触发的频次非常高,间隔很近.如果事件中涉及到大量的位置计算.DOM 操作.元素重绘等工作且这些工作无法在下一个 scroll 事件触发前完成,就会造成浏览器掉帧.加之用户鼠标滚动往往是连续的,就会持续触发 scroll 事件导致掉帧扩大.浏览器 CPU 使用率增加.用户体验受到影响.尤其是在涉及与

javascript中的防抖与节流。

1.什么是防抖?它有什么作用? 什么是防抖?相信行入门的小白,甚至做了一段时间的程序员也不太理解是什么意思,我也是听了公开课才了解一点,现在和大家分享一下我的理解! 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时.比如,在进行窗口的resize.scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕,请求的次数多了浏览器会造成卡

JS防抖和节流

对防抖和节流的一些理解,做一次记录.(之前项目中的需求是在输入框中输入内容之后,调接口返回值,然后不知道还有节流这波操作,然后就写了判断当鼠标失去焦点的时候调接口,后来大佬说可以使用节流来实现) 防抖和节流算起来应该属于性能优化的知识,但是处理不当或者是放任不管就容易引起浏览器卡死.就是在绑定scroll.resize这类事件时,当他发生时,被触发的频率非常高,间隔很近.如果事件中涉及到大量的位置计算.DOM操作.元素重绘等工作且这些工作无法在下一个scroll事件触发前完成,就会造成浏览器调帧

对防抖和节流的理解及其应用场景

在开发中,我们常常会去监听滚动事件或者用户输入框验证事件,如果事件处理没有频率限制,就会加重浏览器的负担,影响用户的体验感, 因此,我们可以采取防抖(debounce)和节流(throttle)来处理,减少调用事件的频率,达到较好的用户体验. 防抖(debounce): 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时,重新出发定时器. <head> <meta charset="UTF-8"> <meta name="viewp

【源码】防抖和节流源码分析

前言 防抖.节流主要用于频繁事件触发,例如鼠标移动.改变窗口大小等.lodash等函数库具备相对应的api, _.debounce ._.throttle. 核心技术:闭包. 区别: 防抖, 连续触发, 第一次和最后一次触发有效 节流, 一段时间内仅触发一次(第一次) 本文以防抖函数为例, 详细说明. 实现 原理, 计时器存储状态. function debounce(fn, delay) { return function() { console.log(fn.timer, count2);

详谈js防抖和节流

本文由小芭乐发表 0. 引入 首先举一个例子: 模拟在输入框输入后做ajax查询请求,没有加入防抖和节流的效果,这里附上完整可执行代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>没有防抖</title> <style type="text/css"></sty

防抖和节流

在前端开发中,有一部分用户行为会频繁的触发事件,而对于DOM操作,资源加载等耗费性能的处理,很可能会导致卡顿,甚至浏览器的崩溃.防抖和节流就是为了解决这一类的问题. window.onscroll = function () { //滚动条位置 let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); } 效果如下 从效果上,我