JavaScript函数节流和函数防抖之间的区别

一、概念解释

函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段。

大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片。由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的。反而形成一种视觉效果,就是一张图。就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样。

同理,可以类推到js代码。在一定时间内,代码执行的次数不一定要非常多。达到一定频率就足够了。因为跑得越多,带来的效果也是一样。倒不如,把js代码的执行次数控制在合理的范围。既能节省浏览器CPU资源,又能让页面浏览更加顺畅,不会因为js的执行而发生卡顿。这就是函数节流和函数防抖要做的事。

函数节流是指一定时间内js方法只跑一次。比如人的眨眼睛,就是一定时间内眨一次。这是函数节流最形象的解释。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。

二、函数节流

函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到。因为滚动事件,是一个高频触发的事件。以下是监听页面元素滚动的示例代码:

// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
 if(!canRun){
 // 判断是否已空闲,如果在执行中,则直接return
 return;
 }
 canRun = false;
 setTimeout(function(){
 console.log("函数节流");
 canRun = true;
 }, 300);
};

函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。

如果空闲,则可以正常触发方法执行。

如果代码正在执行,则取消这次方法执行,直接return。

这个方法的作用是监听ID为throttle元素的滚动事件。

当canRun为true,则代表现在的滚动处理事件是空闲的,可以使用。

通过关卡if(!canRun),等于就拿到了通行证。然后下一步的操作就是立马将关卡关上canRun=false。这样,其他请求执行滚动事件的方法,就被挡回去了。

接着用setTimeout规定最小的时间间隔300,接着再执行setTimeout方法体里面的内容。

最后,等setTimeout里面的方法都执行完毕,才释放关卡canRun=true,允许下一个访问者进来。

这个函数节流的实现形式,需要注意的是执行的间隔时间是>=300ms。如果具体执行的方法是包含callback的,也可以将canRun=true这一步放到callback中。理解了函数节流的关卡设置重点,其实改起来就简单多了。

三、函数防抖

函数防抖的应用场景,最常见的就是用户注册时候的手机号码验证和邮箱验证了。只有等用户输入完毕后,前端才需要检查格式是否正确,如果不正确,再弹出提示语。以下还是以页面元素滚动监听的例子,来进行解析:

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
 clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
 timer = setTimeout(function(){
 console.log("函数防抖");
 }, 300);
};

函数节流的要点,也是需要一个setTimeout来辅助实现。延迟执行需要跑的代码。

如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。

如果计时完毕,没有方法进来访问触发,则执行代码。

这个方法的作用是监听ID为debounce元素的滚动事件

进入滚动事件方法体的时候,做的第一件事就是清除上次未执行的setTimeout。而setTimeout的引用id由变量timer记录。

clearTimeout方法,允许传入无效的值。所以这里直接执行clearTimeout即可。

然后,将需要执行的代码放入setTimeout中,再返回setTimeout引用给timer缓存。

如果倒计时300ms以后,还没有新的方法触发滚动事件,则执行setTimeout中的代码。

函数防抖的实现重点,就是巧用setTimeout做缓存池,而且可以轻易地清除待执行的代码。

其实,用队列的方式也可以做到这种效果。这里就不深入了。

四、在线demo

这是我写的一个测试demo,把鼠标移动到模块上方,滚动滚轮,即可在控制台查看输出效果。

demo地址:https://wall-wxk.github.io/blogDemo/2017/02/15/throttleAndDebounce.html

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • 浅谈JS函数节流防抖

    在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作.资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃.函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的. 函数节流(throttle) 函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行.好像水滴攒到一定重量才会落下一样. 场景: 窗口调整(resize) 页面滚动(scroll) 抢购疯狂点击(mousedown) 实现: function thrott

  • JavaScript函数节流和函数防抖之间的区别

    一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的.反而形成一种视觉效果,就是一张图.就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样. 同理,可以类推到js代码.在一定时间内,代码执行的次数不一定要非常多.达到一定频率就足够了.因为跑得越多,带来的效果也是一样.倒不如,把js代码的执行次数控制在合理的范围.既

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

    问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办? **问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生? 为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说: 这两个方法是在 时间轴上控制函数的执行次数. 函数防抖(debounce) 概念: 在事件被触发n秒后再执行回调,如果在这n秒内

  • JavaScript函数节流和函数去抖知识点学习

    概念 节流 (throttle) 让一个函数不要执行的太频繁,减少执行过快的调用,叫节流 去抖 (debounce) 去抖就是对于一定时间段的连续的函数调用,只让其执行一次 throttle 应用场景 DOM 元素的拖拽功能实现(mousemove) 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹) 计算鼠标移动的距离(mousemove) Canvas 模拟画板功能(mousemove 搜索联想(keyup 监听滚动事件判断是否到页面底部自动加载更多:给 scr

  • 总结JavaScript三种数据存储方式之间的区别

    sessionStorage .localStorage 和 cookie 之间的共同点: 都是保存在浏览器端,且同源的. sessionStorage .localStorage 和 cookie 之间的区别: cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递.而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存.cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下. 存

  • javascript的var与let,const之间的区别详解

    目录 作为全局变量时 变量提升 暂时性死区 块级作用域 重复声明 修改声明的变量(常量与变量声明) 总结 说到JavaScript中声明变量的几种方法也就是var.let.const了,let和const是es6中新增的命令.那么它们之间有什么区别呢? 我们先整体说一下三者的区别,在详细介绍,var.let.const的区别主要从以下几点分析: 作为全局变量时的不同 变量提升 暂时性死区 块级作用域 重复声明 修改声明的变量 作为全局变量时 在ES5中,顶层对象的属性和全局变量是等价的,用var

  • JAVASCRIPT style 中visibility和display之间的区别

    当visibility被设置为"hidden"的时候,元素虽然被隐藏了,但它仍然占据它原来所在的位置. --------------------------------------------------------------- 例子: 复制代码 代码如下: <script language="JavaScript"> function toggleVisibility(me){ if (me.style.visibility=="hidde

  • JavaScript函数防抖与函数节流的定义及使用详解

    目录 一.函数防抖(Debouncing) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 二.函数节流(Throlle) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 一.函数防抖(Debouncing) 1.基本概念 在触发事件后的规定时间内只能执行一次,如果在规定时间内又触发了该事件.则会重新开始计算规定时间: 2.算法思想 (1)首先定义一个函数,函数进入页面立即执行一次,且永远执行最新的一次: (2)返回一个匿名函数: (3)在匿名函数里使用计时器setTimeout

  • JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我触发一个时间时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行,就这样. 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1.

  • JS中setTimeout的巧妙用法前端函数节流

    什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等等事情,那么这时候窗口缩放的时候,有可能连续发多个请求,这并不是我们想要的,或者是说我们常见的鼠标移入移出tab切换效果,有时候连续且移动的很快的时候,会有闪烁的效果,这时候我们就可以使用函数节流来操作.大家都知道,DOM的操作会很消耗或影响性能的,如果是说在窗口缩放的时候,为元素绑定大量的dom操作的话,会引发大量的连续计算,比如

随机推荐