浅谈JavaScript节流和防抖函数

浅谈JavaScript节流和防抖函数

前言

在前端开发中,我们经常会遇到需要监听用户操作并执行相应任务的情况,例如用户在搜索框中输入关键词时,会实时通过ajax请求获取匹配结果;用户在滚动页面时,会自动加载更多的内容等等。但是由于用户的操作往往不可预测,当用户频繁进行操作时,会导致一些性能问题,如频繁地发送请求,重复执行相同的逻辑等等。这时候,就需要用到节流和防抖函数来限制这种不必要的操作。

节流函数(throttle)

节流函数是指在一段时间内,只执行一次事件。它可以避免一些高频率调用的事件,使其被间隔执行。常见的节流函数有时间戳版本和定时器版本。时间戳版本即指在固定时间内执行一次时间函数,而定时器版本则是在固定时间后执行一次事件。

以定时器版本为例,其基本模板代码为:

function throttle(func, delay) {
  let canRun = true;
  return function() {
    if (!canRun) return;
    canRun = false;
    setTimeout(() => {
      func.call(this, ...arguments);
      canRun = true;
    }, delay);
  };
}

在上述代码中,canRun表示此时函数能否执行的标志,在未达到规定时间时,其为false,在达到规定时间后,其变为true,以便下一次可以执行函数。在函数执行前将canRun标记为false,并将当次执行函数的参数延迟到delay后才执行。 这才是节流执行的精髓所在。

接下来,我们来看一个实例,通过点击一次按钮打印当前时间,并且确保在一定时间间隔内只执行一次。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>throttle示例</title>
  </head>
  <body>
    <button id="btn">点击弹出当前时间</button>
    <script>
      function throttle(func, delay) {
        let canRun = true;
        return function () {
          if (!canRun) return;
          canRun = false;
          setTimeout(() => {
            func.call(this, ...arguments);
            canRun = true;
          }, delay);
        };
      }
      let clickHandler = throttle(function () {
        console.log(new Date().toLocaleTimeString());
      }, 1000);
      document.getElementById('btn').addEventListener('click', clickHandler);
    </script>
  </body>
</html>

在上述示例中,当我们点击按钮后,函数会在1秒后输出当前时间,即使我们快速点击多次,也只会在1秒后输出最后一次操作的时间。

防抖函数(debounce)

防抖函数也是用于避免函数的重复执行,但是相比节流函数,它是在每次事件结束后规定时间再执行事件,而不是固定时间内只执行一次事件。这样,在函数执行后,如果用户继续操作,则计时器被清空,重新规定事件。

以定时器版本为例,其基本模板代码为:

function debounce(func, delay) {
  let timer = null;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(this,...arguments);
    },delay);
  };
}

在上述代码中,timer表示setTimeout函数的返回值,在每次函数执行前清除上次setTimeout事件,调用最新的setTimeout事件来执行新的函数。调用方法如下:

let debouncedFunc = debounce(function () {
  console.log(new Date().toLocaleTimeString());
}, 1000);

接下来,我们来看一个实例,限制滚动事件每500ms触发一次:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>debounce示例</title>
  </head>
  <body>
    <div style="height: 2000px"></div>
    <script>
      function debounce(func, delay) {
        let timer = null;
        return function () {
          clearTimeout(timer);
          timer = setTimeout(() => {
            func.call(this, ...arguments);
          }, delay);
        };
      }
      window.onscroll = debounce(function () {
        console.log(new Date().toLocaleTimeString());
      }, 500);
    </script>
  </body>
</html>

在上述示例中,当我们滚动页面时,函数会在500毫秒后输出当前时间,如果在500ms内连续滚动,只会在最后一次滚动结束后500ms输出时间。

总结

节流和防抖函数虽然在代码结构上十分相似,但是还是有一些区别的。防抖函数是在一定时间后执行事件,进行了时间避免错误,而节流函数则是规定在特定时间内只执行一次事件。在实际开发中,需要根据具体情况选择节流函数或防抖函数进行优化,从而减少对性能的影响。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈JavaScript节流和防抖函数 - Python技术站

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

相关文章

  • JavaScript 对任意元素,自定义右键菜单的实现方法

    实现自定义右键菜单的方法主要分为以下几步: 绑定鼠标右键事件 创建菜单元素 定位菜单元素 显示/隐藏菜单元素 处理菜单项的操作 具体地实现方式如下: 1. 绑定鼠标右键事件 我们可以通过监听 contextmenu 事件来实现右键菜单的显示。该事件是当用户在某个元素上右键点击鼠标时触发的。 示例代码如下: document.addEventListener(…

    JavaScript 2023年6月10日
    00
  • JS定时器不可靠的原因及解决方案

    JS定时器不可靠的原因及解决方案 什么是JS定时器? JS中有两种类型的定时器: setTimeout setInterval 这两个函数都是用来定时执行某些代码的。setTimeout函数会在指定的时间后执行一次性的操作,而setInterval会每隔指定时间执行一次操作。 JS定时器的不可靠性 JS定时器不可靠的原因是因为定时器的执行是基于事件循环机制的…

    JavaScript 2023年5月28日
    00
  • javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)

    下面我来为你详细讲解“javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)”的攻略。 JavaScript数组对象常用api函数小结 连接数组 concat:连接两个或多个数组,返回新的数组对象。 示例: const arr1 = [‘a’, ‘b’]; const arr2 = [‘c’]; const arr3 = [‘d’,…

    JavaScript 2023年5月27日
    00
  • ES6新特性之类(Class)和继承(Extends)相关概念与用法分析

    下面是关于ES6中类(class)和继承(extends)的详细讲解: 什么是类(class) 类(class)是ES6中的一个新特性,是一种对象构造器,它可以通过类来创建对象,其语法定义如下: class MyClass { // 类的构造方法,当通过new关键字实例化类对象时,会调用这个方法来初始化对象的属性 constructor(args) { //…

    JavaScript 2023年5月28日
    00
  • JavaScript的三种BOM对象

    当我们使用JavaScript编写网页时,页面中除了DOM对象,还有BOM对象,BOM是指浏览器对象模型,它提供了许多与浏览器交互的对象和方法。JavaScript中BOM对象可分为三类:窗口对象、导航对象和屏幕对象。下面就分别来详细讲解这三种BOM对象: 窗口对象 窗口对象是BOM中最常用的对象,它代表整个浏览器窗口或选项卡。窗口对象是通过window对象…

    JavaScript 2023年5月27日
    00
  • JQuery 动态扩展对象之另类视角

    JQuery 动态扩展对象之另类视角 在 Javascript 中,对象是一种灵活的数据类型,可以随意添加、删除、修改属性。JQuery 作为一个基于 Javascript 的库,提供了很多方便的方法和 API,其中一个非常常用的功能就是动态扩展对象。这篇文章将介绍 JQuery 中动态扩展对象的另一种视角,希望对初学者来说有所帮助。 对象的动态扩展 在 J…

    JavaScript 2023年6月10日
    00
  • js日历控件(可精确到分钟)

    首先介绍一下JS日历控件的基础要素: HTML结构 <input type="text" id="input-time" name="time" placeholder="选择时间" readonly> CSS样式 这里我们采用了Bootstrap的样式,如果你没有引…

    JavaScript 2023年5月27日
    00
  • javascript中Date对象的使用总结

    下面就是一份详细的“JavaScript中Date对象的使用总结”攻略。 1. 引言 在JavaScript中,Date对象是处理日期和时间的重要组件,它提供了很多常见的日期和时间操作方法。本文将简要介绍Date对象的基本用法和常用方法。 2. 创建Date对象 可以使用new Date()语法创建一个Date对象,表示当前日期和时间: const date…

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