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

引言:

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

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

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

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

二、如何实现节流函数?

实现思路:

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

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日

相关文章

  • Javascript入门学习第二篇 js类型第1/2页

    以下是“Javascript入门学习第二篇 js类型第1/2页”的完整攻略: Javascript类型 Javascript是一种弱类型语言,因此不需要在声明变量时指定变量的类型。Javascript中的类型可以分为以下几类: 原始类型(primitive types):包括数字(number)、字符串(string)、布尔值(boolean)、空(null…

    JavaScript 2023年6月10日
    00
  • 你必须了解的JavaScript中的属性描述对象详解(下)

    让我来详细讲解一下“你必须了解的JavaScript中的属性描述对象详解(下)”中的内容。 引言 在 JavaScript 中,所有的属性都是以属性描述对象的形式存在的。属性描述对象是一个包含属性元数据的对象,可以控制属性的行为。在 上一篇攻略 中,我已经介绍了属性描述对象的基础知识,接下来我将继续介绍更加深入和实用的知识。 属性描述对象的属性 config…

    JavaScript 2023年5月27日
    00
  • Javascript读取上传文件内容/类型/字节数

    下面是Javascript读取上传文件内容/类型/字节数的完整攻略。 1. 读取上传文件类型 实现读取上传文件类型的方法,可以使用HTML5标准中的File API。通过File API,可以使用JS访问用户选择的本地文件。 以下是一个使用File API的示例代码: const fileInput = document.getElementById(‘fi…

    JavaScript 2023年5月27日
    00
  • javascript HTML5文件上传FileReader API

    下面是关于JavaScript HTML5文件上传FileReader API的详细攻略: 什么是FileReader API? FileReader API 是 HTML5 中的一款文件读取 API,使得客户端的 web 应用程序能够异步读取文件(即用户计算机中的本地文件,而不是通过网络获取的文件)。可以使用 FileReader 读取文本文件、二进制文件…

    JavaScript 2023年5月27日
    00
  • Vue nextTick的原理解析

    Vue.js中的nextTick方法是一个非常有用又有些神秘的工具。其背后的原理和使用方式值得我们深入探究和理解,使我们能够更好地使用Vue.js,写出更加优秀的代码。 什么是nextTick? 在Vue.js中,当我们修改了一个数据后,DOM并不会立刻更新。相反,Vue.js会在内部异步的更新DOM。这种异步更新意味着我们不能马上获取到更新后的DOM,这对…

    JavaScript 2023年6月11日
    00
  • 利用js编写网页进度条效果

    编写网页进度条效果通常需要用到JavaScript语言。下面是利用JS编写网页进度条效果的几个步骤: 1. 创建进度条的HTML布局 首先,你需要确定进度条的位置和尺寸,并在HTML中创建一个<div>元素作为进度条容器,在这个容器内放置一个表示进度的<div>子元素。 示例1:简单的进度条布局 <div class=&quot…

    JavaScript 2023年6月11日
    00
  • js canvas实现圆形流水动画

    下面是详细的js canvas实现圆形流水动画的攻略: 1. 准备工作 在HTML中,我们需要创建一个canvas元素,用于显示流水效果。 <canvas id="myCanvas"></canvas> 在JavaScript中,我们需要获取该canvas元素,并在其中绘制圆形流水。需要注意:canvas绘图需要在…

    JavaScript 2023年6月10日
    00
  • js判断是否有中文的脚本_js判断中文方法集合 原创

    标题:JS判断是否有中文的脚本 JS代码: /** * 判断字符串中是否存在中文字符 * @param {string} str – 待判断的字符串 * @returns {boolean} – 如果存在中文字符则返回true,否则返回false */ function hasChineseCharacter(str) { // 使用正则表达式进行匹配 va…

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