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

引言:

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

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

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

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

二、如何实现节流函数?

实现思路:

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

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日

相关文章

  • 23个Javascript弹出窗口特效整理

    这篇文章是对23个Javascript弹出窗口特效的整理,其中包含了不同类型的弹窗特效,包括提示框、模态框、响应式弹窗等。本文将对这些弹窗特效进行详细讲解,帮助读者更好地理解和使用这些特效。 1. 弹出提示框 提示框可以用来展示简单的信息,并通知用户进行确认或取消操作。下面是一个例子: <button onclick="alert(‘Hell…

    JavaScript 2023年5月28日
    00
  • javascript真的不难-回顾一下基础知识

    “JavaScript真的不难-回顾一下基础知识”攻略 介绍 本篇攻略旨在回顾JavaScript的基础知识,帮助初学者系统地学习并理解这门语言。 JavaScript是一门广泛应用于网页设计的编程语言,它能给网页带来丰富的交互体验。学好JavaScript是现代网页设计中最重要的一步。 JavaScript语法 变量与数据类型 在JavaScript中,我…

    JavaScript 2023年5月28日
    00
  • 如何使Chrome控制台支持多行js模式——意外发现

    下面是讲解“如何使Chrome控制台支持多行js模式——意外发现”的完整攻略: 1. 问题描述 当我们在Chrome控制台输入多行的JavaScript代码时,按下回车键后会将当前行代码执行。如果我们输入多行代码,需要将所有输入的代码都复制到单行去将它们一起执行。这不仅耗时,操作起来也不太方便。那么有没有办法支持多行JavaScript模式呢? 2. 解决方…

    JavaScript 2023年6月11日
    00
  • JavaScript 函数式编程的原理

    JavaScript函数式编程的原理 什么是函数式编程 函数式编程(Functional Programming,简称FP)是一种编程范式,它把计算机运算视为对数学上函数的运用和组合。不同于命令式范式,函数式编程没有程序状态的概念,只有函数输入、输出的概念,你可以看作是由一组输入及对应的输出组成的数学函数。在函数式编程中,函数是一等公民,函数可以作为参数传递…

    JavaScript 2023年5月27日
    00
  • js中键盘事件实例简析

    js中键盘事件实例简析 键盘事件是Web开发中十分常用的事件之一,掌握了它的使用方法可以大大提高效率和用户体验。这篇文章将从以下两个方面介绍js中键盘事件的相关知识:键盘事件类型和键盘事件的应用 键盘事件类型 onKeyDown 键盘按下触发。按住不放会不断触发该事件。 onKeyPress 键盘按下并放开后触发。 onKeyUp 键盘放开后触发。和按下事件…

    JavaScript 2023年6月11日
    00
  • JavaScript 时分秒时间代码(自动补零)

    关于JavaScript时分秒时间代码的自动补零,我们可以采用以下两种方式实现: 1. 使用自带方法 padStart() 该方法可以在字符串前添加指定数量的字符,从而实现自动补零。具体参考以下示例代码: // 获取当前时间 const now = new Date(); // 获取时分秒 const hour = now.getHours(); const…

    JavaScript 2023年5月27日
    00
  • 9种使用Chrome Firefox 自带调试工具调试javascript技巧

    当我们开发JavaScript程序的时候,难免会遇到一些问题,这时候使用调试工具就是非常必要的。Chrome和Firefox浏览器都自带了调试工具,本文将详细讲解9种使用Chrome和Firefox自带调试工具调试JavaScript的技巧。 1. 加断点 在代码中加入断点是调试的入门级技巧。断点可以让程序在指定的语句处停下来,并可以查看当前的变量值以及执行…

    JavaScript 2023年6月11日
    00
  • JavaScript中string转换成number介绍

    当需要在JavaScript中使用数字时,需要将字符串转换为数字。在JavaScript中有三种方式可以将字符串转换为数字类型:Number(), parseInt() 和 parseFloat()。下面对这三种方式进行详细介绍。 Number()方法: Number()方法可以把任何JavaScript对象转换为数字。如果对象是一个字符串,字符串只包含数字…

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