一文看懂如何简单实现节流函数和防抖函数

引言:

在前端开发中,我们常常需要处理一系列与用户交互相关的事件,如滚动、键盘输入、鼠标移动等等。这些事件会频繁触发,造成过多的资源浪费,因此需要使用节流和防抖函数来解决这个问题。本文将详细讲解如何实现节流和防抖函数。

一、什么是节流函数和防抖函数?

节流函数:在一段时间内,只执行一次函数。比如,一个页面上有多个滚动事件,如果每一次滚动都触发事件处理函数,可能会对性能造成影响,因此我们需要一个函数来控制一个时间段内只执行一次事件处理函数,以节约资源,这就是节流函数。

防抖函数:在一段时间内,如果多次触发同一个事件,只有最后一次触发的事件会执行函数。比如,一个搜索框需要根据用户输入的关键字动态显示数据,如果对于每一次输入都要请求一次数据,会影响性能,因此我们需要一个函数来控制一定时间内只有最后一次输入才会请求数据,这就是防抖函数。

二、如何实现节流函数?

实现思路:

使用时间戳,记录上一次执行函数的时间。
设定一个时间间隔,如果当前时间减去上一次执行函数的时间大于等于这个时间间隔,就执行函数,并更新上一次执行函数的时间。
代码示例:

function throttle(fn, delay) {
  let timer = null;
  let start_time = 0;

  return function() {
    let current_time = +new Date();
    let diff = current_time - start_time;

    if (!start_time || diff >= delay) {
      fn.apply(this, arguments);
      start_time = current_time;
    } else if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        start_time = +new Date();
        timer = null;
      }, delay - diff);
    }
  }
}

代码解析:

使用闭包保存定时器变量 timer 和上一次执行函数的时间 start_time。
计算当前时间和上一次执行函数的时间差 diff,如果 diff 大于等于时间间隔 delay 或者还没有执行过函数,则执行函数,并更新 start_time。
如果 diff 小于时间间隔 delay,说明还没有到时间间隔,此时需要使用定时器 setTimeout 来控制函数的执行,直到等待的时间间隔 delay 到达后,才执行函数并更新 start_time 以及清空定时器 timer。

三、如何实现防抖函数?

实现思路:

使用定时器和闭包,记录上一次触发事件的时间。
设定一个时间间隔,如果当前时间减去上一次触发事件的时间小于这个时间间隔,就清空定时器并重新设定一个新的定时器,等待下一次触发事件。
如果当前时间减去上一次触发事件的时间大于等于时间间隔,则执行函数并重新记录上一次触发事件的时间。
代码示例:

function debounce(fn, delay) {
  let timer = null;

  return function() {
    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay);
  }
}

代码解析:

使用闭包保存定时器变量 timer。
如果在时间间隔内再次触发事件,则清空定时器并重新设定一个新的定时器。
如果时间间隔后触发事件,则执行函数,并清空定时器 timer。

四、实战示例

接下来我们用一个实战示例来演示如何使用节流和防抖函数。

实现需求:

当浏览器窗口滚动时,输出对应窗口位置的 top 值和 left 值,并使用节流函数和防抖函数来控制输出频率。

代码示例:

// 节流函数实现
function throttle(fn, delay) {
  let timer = null;
  let start_time = 0;

  return function() {
    let current_time = +new Date();
    let diff = current_time - start_time;

    if (!start_time || diff >= delay) {
      fn.apply(this, arguments);
      start_time = current_time;
    } else if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        start_time = +new Date();
        timer = null;
      }, delay - diff);
    }
  }
}

// 防抖函数实现
function debounce(fn, delay) {
  let timer = null;

  return function() {
    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay);
  }
}

let output1 = throttle(() => {
  console.log(`window top: ${window.scrollY}`);
  console.log(`window left: ${window.scrollX}`);
}, 200);

let output2 = debounce(() => {
  console.log(`window top: ${window.scrollY}`);
  console.log(`window left: ${window.scrollX}`);
}, 200);

window.addEventListener('scroll', () => {
  output1();
  output2();
});

代码解析:

定义节流函数 throttle 和防抖函数 debounce。
使用节流函数和防抖函数来处理输出函数,控制输出频率。
在滚动事件上添加事件监听器,分别使用上述定义的节流函数和防抖函数来输出窗口的 top 值和 left 值。

总结:

本文详细讲解了如何使用节流函数和防抖函数来控制事件的频次,从而提高页面的性能。同时,本文还给出了相关的代码实现,并进行了详细解释和分析。希望本文能够对你的前端开发工作有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文看懂如何简单实现节流函数和防抖函数 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 详解JS数组方法

    详解JavaScript数组方法 概述 JavaScript中数组(Array)是一种非常常用的数据结构,它们通常用于存储一系列的值。在JavaScript中,数组具有以下特点: 数组是一种有序的集合,每个元素都有一个索引。 数组的长度是可变的,可以随时添加或删除元素。 数组可以存储不同类型的值,例如数字、字符串、对象等。 JavaScript数组中常用的方…

    JavaScript 2023年5月18日
    00
  • JQuery中的$.getJSON 使用说明

    以下是关于JQuery中的$.getJSON()使用说明的完整攻略: 1. 概述 $.getJSON()是JQuery中用来发送JSON格式请求并获取响应结果的函数。其基本用法为:$.getJSON(url, [data], [success])。 其中,url表示数据请求的url,data是可选的请求参数,success是请求成功后的回调函数。 2. 示例…

    JavaScript 2023年5月27日
    00
  • Node.js的特点和应用场景介绍

    Node.js的特点和应用场景介绍 什么是Node.js Node.js是基于Chrome V8 JavaScript引擎的一个开源、跨平台的JavaScript运行环境。通过Node.js可以使用JavaScript进行服务器端的开发,以及命令行工具的编写。 Node.js的特点 异步IO Node.js采用事件驱动、非阻塞式IO的编程模型,使得模块之间的…

    JavaScript 2023年5月28日
    00
  • bootstrap fileinput 上传插件的基础使用

    下面是针对Bootstrap FileInput上传插件的基础使用攻略。 介绍 Bootstrap FileInput是一款基于Bootstrap框架的文件上传插件,支持多文件上传、进度条展示、预览等功能,可以应用于各种网站和应用中。在本文中,我们将介绍Bootstrap FileInput的基础用法,包括引入和配置等方面。 引入文件 首先,在你的HTML文…

    JavaScript 2023年5月28日
    00
  • WebRTC媒体权限申请getUserMedia实例详解

    WebRTC媒体权限申请getUserMedia实例详解 WebRTC 是一个支持浏览器进行实时语音和视频通信的技术,该技术支持在浏览器中进行点对点的实时通信,如音视频聊天、语音识别等。其中要求涉及到媒体流的获取、媒体流的处理和媒体流的展示,其中媒体权限申请可以使用 getUserMedia 接口实现。 什么是 getUserMedia 接口? getUse…

    JavaScript 2023年6月11日
    00
  • 使用JavaScript 实现对象 匀速/变速运动的方法

    我会详细讲解使用JavaScript实现对象匀速/变速运动的方法的完整攻略。 使用JavaScript 实现对象 匀速运动的方法 匀速运动的基本原理 在匀速运动的过程中,物体在相等时间内移动的距离相等。例如一个跑步运动员以每秒10米的速度前进,则经过1秒后,他的位置与再过1秒后的位置的距离是相等的,也就是说他走过了20米。 在JavaScript实现对象匀速…

    JavaScript 2023年5月27日
    00
  • 将字符串中由空格隔开的每个单词首字母大写

    要将字符串中由空格隔开的每个单词首字母大写,可以使用字符串操作方法和正则表达式。 步骤如下: 首先要将字符串进行拆分,将每个单词分离。可以使用split()方法,该方法可以按照指定字符或正则表达式对字符串进行分割,返回一个由分割出来的子字符串组成的数组。 例如: let str = "hello world"; let arr = str…

    JavaScript 2023年6月11日
    00
  • 解析JavaScript中的不可见数据类型

    首先我们需要了解JavaScript中的不可见数据类型。 JavaScript中有七种数据类型:Undefined、Null、Boolean、Number、String、Object和Symbol(ES6新增)。其中Undefined和Null可以称为“空数据类型”,因为它们只有一个值:undefined和null。但是这两个值在JavaScript的底层实…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部