当前位置: 首页 > 编程笔记 >

js防抖和节流的深入讲解

娄飞鸾
2023-03-14
本文向大家介绍js防抖和节流的深入讲解,包括了js防抖和节流的深入讲解的使用技巧和注意事项,需要的朋友参考一下

前言:

我们在做页面事件绑定的时候,经常要进行节流处理,比如鼠标异步点击,去执行一个异步请求时,需要让它在上一次没执行时不能再点击,又或者绑定滚动事件,这种持续触发进行dom判断的时候,就要按一定频率的执行。

本文主要给大家介绍了关于js防抖和节流的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

0. 引入

首先举一个例子:

模拟在输入框输入后做ajax查询请求,没有加入防抖和节流的效果,这里附上完整可执行代码:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <title>没有防抖</title>
 <style type="text/css"></style>
 <script type="text/javascript">
 window.onload = function () {
 //模拟ajax请求
 function ajax(content) {
 console.log('ajax request ' + content)
 }
 let inputNormal = document.getElementById('normal');

 inputNormal.addEventListener('keyup', function (e) {
 ajax(e.target.value)
 })
 }
 </script>
</head>

<body>
 <div>
 1.没有防抖的输入:
 <input type="text" name="normal" id="normal">
 </div>
</body>

</html>

效果:在输入框里输入一个,就会触发一次“ajax请求”(此处是console)。


没有防抖和节流

缺点:浪费请求资源,可以加入防抖和节流来优化一下。

本文会分别介绍什么是防抖和节流,它们的应用场景,和实现方式。防抖和节流都是为了解决短时间内大量触发某函数而导致的性能问题,比如触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。但二者应对的业务需求不一样,所以实现的原理也不一样,下面具体来看看吧。

1. 防抖(debounce)

1.1 什么是防抖

在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时。

1.2 应用场景

(1) 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;

(2) window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;

1.3 实现

还是上述列子,这里加入防抖来优化一下,完整代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <title>加入防抖</title>
 <style type="text/css"></style>
 <script type="text/javascript">
 window.onload = function () {
  //模拟ajax请求
  function ajax(content) {
  console.log('ajax request ' + content)
  }
  function debounce(fun, delay) {
  return function (args) {
   //获取函数的作用域和变量
   let that = this
   let _args = args
   //每次事件被触发,都会清除当前的timeer,然后重写设置超时调用
   clearTimeout(fun.id)
   fun.id = setTimeout(function () {
   fun.call(that, _args)
   }, delay)
  }
  }
  let inputDebounce = document.getElementById('debounce')
  let debounceAjax = debounce(ajax, 500)
  inputDebounce.addEventListener('keyup', function (e) {
  debounceAjax(e.target.value)
  })
 }
 </script>
</head>

<body>
 <div>
 2.加入防抖后的输入:
 <input type="text" name="debounce" id="debounce">
 </div>
</body>

</html>

代码说明:

1.每一次事件被触发,都会清除当前的 timer 然后重新设置超时调用,即重新计时。 这就会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发;

2.只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行;

效果:

加入防抖后,当持续在输入框里输入时,并不会发送请求,只有当在指定时间间隔内没有再输入时,才会发送请求。如果先停止输入,但是在指定间隔内又输入,会重新触发计时。

加入防抖

2.节流(throttle)

2.1 什么是节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

2.2 应用场景

(1)鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;

(2)在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;

(3)监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;

2.3 实现

还是上述列子,这里加入节流来优化一下,完整代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <title>加入节流</title>
 <style type="text/css"></style>
 <script type="text/javascript">
 window.onload = function () {
  //模拟ajax请求
  function ajax(content) {
  console.log('ajax request ' + content)
  }

  function throttle(fun, delay) {
  let last, deferTimer
  return function (args) {
   let that = this;
   let _args = arguments;

   let now = +new Date();
   if (last && now < last + delay) {
   clearTimeout(deferTimer);
   deferTimer = setTimeout(function () {
    last = now;
    fun.apply(that, _args);
   }, delay)
   } else {
   last = now;
   fun.apply(that, _args);
   }
  }
  }
  let throttleAjax = throttle(ajax, 1000)
  let inputThrottle = document.getElementById('throttle')
  inputThrottle.addEventListener('keyup', function (e) {
  throttleAjax(e.target.value)
  })
 }
 </script>
</head>

<body>
 <div>
 3.加入节流后的输入:
 <input type="text" name="throttle" id="throttle">
 </div>
</body>

</html>

效果:实验可发现在持续输入时,会安装代码中的设定,每1秒执行一次ajax请求


加入节流

3. 小结

总结下防抖和节流的区别:

-- 效果:

函数防抖是某一段时间内只执行一次;而函数节流是间隔时间执行,不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。

-- 原理:

防抖是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发。

节流是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。

 类似资料:
  • 本文向大家介绍js的节流和防抖?相关面试题,主要包含被问及js的节流和防抖?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: http://www.cnblogs.com/coco1s/p/5499469.html 参考回答: 必要性:由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分

  • 本文向大家介绍深入了解JavaScript 防抖和节流,包括了深入了解JavaScript 防抖和节流的使用技巧和注意事项,需要的朋友参考一下 概述 说明 在项目过程中,经常会遇到一个按钮被多次点击并且多次调用对应处理函数的问题,而往往我们只需去调用一次处理函数即可。有时也会遇到需要在某一规则内有规律的去触发对应的处理函数,所以就需要使用到函数防抖与函数节流来帮助我们实现我们想要的结果以及避免不必

  • 本文向大家介绍浅谈JS函数节流防抖,包括了浅谈JS函数节流防抖的使用技巧和注意事项,需要的朋友参考一下 在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的。 函数节流(throttle) 函数节流就是预定一个函数只有在大于等于执

  • 何谓节流和防抖? 节流 节流的意思是,规定时间内,只触发一次。比如我们设定500ms,在这个时间内,无论点击按钮多少次,它都只会触发一次。具体场景可以是抢购时候,由于有无数人 快速点击按钮,如果每次点击都发送请求,就会给服务器造成巨大的压力,但是我们进行节流后,就会大大减少请求的次数。 防抖 防抖的意思是,在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判

  • 本文向大家介绍JS中的防抖与节流及作用详解,包括了JS中的防抖与节流及作用详解的使用技巧和注意事项,需要的朋友参考一下 概念 函数防抖(debounce)是指在一定时间内,在动作被连续频繁触发的情况下,动作只会被执行一次,也就是说当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间,所以短时间内的连续动作永远只会触发一次,比如说用手指一直按住一个弹簧,它将不会弹起直

  • 本文向大家介绍JS函数节流和函数防抖问题分析,包括了JS函数节流和函数防抖问题分析的使用技巧和注意事项,需要的朋友参考一下 问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办?   **问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,

  • 本文向大家介绍浅析JavaScript 函数防抖和节流,包括了浅析JavaScript 函数防抖和节流的使用技巧和注意事项,需要的朋友参考一下 函数防抖和节流都是对高频动作触发回调函数的一个优化,实现方式上有类似之处。先从使用场景做个区分。 防抖使用场景: 表单输入框校验 提交按钮避免重复提交 节流使用场景: scroll,mousemove,resize等 函数防抖(debounce) 表单输入

  • 本文向大家介绍js中Generator函数的深入讲解,包括了js中Generator函数的深入讲解的使用技巧和注意事项,需要的朋友参考一下 前言 Generator函数是es6提供的一种异步编程的解决方案,语法行为与传统函数完全不一样。 Generator函数有多种理解角度,从语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态。 执 行Generator函数会返回一