JS函数节流和函数防抖问题分析

 更新时间:2017年12月18日 13:48:12   作者:ACERY1  
这篇文章主要介绍了JS函数节流和函数防抖问题分析,非常不错,具有参考借鉴价值,需要的朋友可以参考下

问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办?

 

**问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生?

为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说:

这两个方法是在 时间轴上控制函数的执行次数。

函数防抖(debounce)

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

生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流(throttle)

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

生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。

分析图

假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。

如果触发事件的频率是 0.5s/次 ,那么函数防抖如图

 

因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。

函数节流如图

 

因为控制了最多一秒一次,频率为 0.5s/次 ,所以每一秒钟就有一次事件作废。最终控制成 1s/次

如果触发事件的频率是 2s/次 ,那么

函数防抖如图

 

因为 2s/次
已经大于了规定的最小时间,所以每计时两秒便触发一次。

函数节流如图

 

同样, 2s/次 大于了最小时间规定,所以每一次触发都生效。

应用场景

对于函数防抖,有以下几种应用场景:

  • 给按钮加函数防抖防止表单多次提交。
  • 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
  • 判断 scroll 是否滑到底部, 滚动事件 + 函数防抖

总的来说,适合多次事件 一次响应 的情况

对于函数节流,有如下几个场景:

  • 游戏中的刷新率
  • DOM元素拖拽
  • Canvas画笔功能

总的来说,适合 大量事件 按时间做 平均 分配触发。

源码

函数防抖:

function debounce(fn, wait) {
 var timer = null;
 return function () {
  var context = this
  var args = arguments
  if (timer) {
   clearTimeout(timer);
   timer = null;
  }
  timer = setTimeout(function () {
   fn.apply(context, args)
  }, wait)
 }
}
var fn = function () {
 console.log('boom')
}
setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次
setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)

之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是 timer 。

函数节流

function throttle(fn, gapTime) {
 let _lastTime = null;
 return function () {
 let _nowTime = + new Date()
 if (_nowTime - _lastTime > gapTime || !_lastTime) {
  fn();
  _lastTime = _nowTime
 }
 }
}
let fn = ()=>{
 console.log('boom')
}
setInterval(throttle(fn,1000),10)

如图是实现的一个简单的函数节流,结果是 一秒打出一次boom

总结

以上所述是小编给大家介绍的JS函数节流和函数防抖问题分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 解决layui前端框架 form表单,table表等内置控件不显示的问题

    解决layui前端框架 form表单,table表等内置控件不显示的问题

    今天小编就为大家分享一篇解决layui前端框架 form表单,table表等内置控件不显示的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 简单谈谈gulp-changed插件

    简单谈谈gulp-changed插件

    这篇文章主要介绍了关于gulp-changed插件的相关资料,文中介绍的还是相对详细的,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • JavaScript axios安装与封装案例详解

    JavaScript axios安装与封装案例详解

    这篇文章主要介绍了JavaScript axios安装与封装案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • JS如何设置滚动属性默认自动滚动到底部(overflow:scroll;)

    JS如何设置滚动属性默认自动滚动到底部(overflow:scroll;)

    这篇文章主要给大家介绍了关于JS如何设置滚动属性默认自动滚动到底部(overflow:scroll;)的相关资料,通过本文介绍的的JavaScript代码示例,你可以实现滚动条默认在最底部的效果,需要的朋友可以参考下
    2023-10-10
  • 原生JS实现拖拽图片效果

    原生JS实现拖拽图片效果

    这篇文章主要为大家详细介绍了原生JS实现拖拽图片效果,JS实现图标图拖拽,拖拽的过程中不断输出该div的left、top值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • javascript返回顶部的按钮实现方法

    javascript返回顶部的按钮实现方法

    这篇文章主要介绍了javascript返回顶部的按钮实现方法,需要的朋友可以参考下
    2016-01-01
  • JS制作适用于手机和电脑的通知信息效果

    JS制作适用于手机和电脑的通知信息效果

    这篇文章主要介绍了JS制作适用于手机和电脑的通知信息效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • JavaScript自定义鼠标右键菜单栏

    JavaScript自定义鼠标右键菜单栏

    这篇文章主要为大家详细介绍了JavaScript自定义鼠标右键菜单栏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 11个ES13中令人惊叹的JavaScript新特性总结

    11个ES13中令人惊叹的JavaScript新特性总结

    与许多其他编程语言一样,JavaScript 也在不断发展,小编今天就为大家介绍ES13中添加的最新功能,并查看其用法示例以更好地理解它们,有需要的小伙伴可以了解下
    2023-09-09
  • js 调整select 位置的函数

    js 调整select 位置的函数

    js 调整select 位置的函数,向上移动,向下移动,移动到最上,移动到最后 这里把项目中写过的几个js函数来给大家分享,功能是通过js来实现对select 中的option的位置进行移动,代码如下
    2008-02-02

最新评论