javascript函数的节流[throttle]与防抖[debounce]


Posted in Javascript onNovember 15, 2017

防抖和节流

窗口的resize、scroll,输入框内容校验等操作时,如果这些操作处理函数较为复杂或页面频繁重渲染等操作时,如果事件触发的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少触发的频率,同时又不影响实际效果。

这两个东西都是为了项目优化而出现的,官方是没有具体定义的,他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等问题;

像这类事件一般像 scroll keyup mousemove resize等等,短时间内不断的触发,在性能上消耗是非常大的,尤其是一些改变DOM结构的操作;

节流[throttle]与防抖[debounce]非常相似,都是让上述这类事件在规定的事件从不断的去触发更改成为规定的时间内触发多少次;

节流[throttle]

节流通俗来解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,这个秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴,这,,,好吧这就是我们节流的概念;

换成函数来说,使用setTimeout方法,给定两个时间,后面的时间减去前面的时间,到达我们给定的时间就去触发一次这个事件,这么说太笼统的,我们看下面的函数,这里我们以【scroll】为例;

/** 样式我就顺便写了 **/
<style>
 *{padding:0;margin:0;}
 .scroll-box{
  width : 100%;
  height : 500px;
  background:blue;
  overflow : auto;
 } 
 .scroll-item{
  height:1000px;
  width:100%;
 }
</style>

------------------------

/** 先给定DOM结构;**/
<div class="scroll-box">
 <div class="scroll-item"></div>
</div>

------------------------

/**主要看js,为了简单我用JQ去写了**/
<script>
 $(document).ready(function(){
  var scrollBox = $('.scroll-box');
  //调用throttle函数,传入相应的方法和规定的时间;
  var thro = throttle(throFun,300);
  //触发事件;
  scrollBox.on('scroll' , function(){
   //调用执行函数;
   thro();
  })

  // 封装函数; 
  function throttle(method,time){
   var timer = null;
   var startTime = new Date();
   return function(){
    var context = this;
    var endTime = new Date();
    var resTime = endTime - startTime;
    //判断大于等于我们给的时间采取执行函数;
    if(resTime >= time){
     method.call(context);
     //执行完函数之后重置初始时间,等于最后一次触发的时间
     startTime = endTime;
    }
   }
  }
  function throFun(){
   console.log('success');
  }
 })
</script>

通过以上的函数,我们就可以做到节流的效果,在规定的每300毫秒触发一次,当然时间可以自定义,根据需求来;

防抖[debounce ]

写代码之前,我们先清楚一下防抖的概念,不知道大家有没有做过电脑端两边悬浮广告窗口的这么一个东西,当我们拖动滚动条的时候,两边的广告窗口会因为滚动条的拖动,而不断的尝试着去居于中间,然后你就会看到这两个窗口,不停的抖啊抖;

一般这种就叫抖动了,我们要做的就是防止这种抖动,称为防抖[debounce ];

那这里防抖思想就是当我们拖动完成之后,两边的窗口位置再重新去计算,这样,就会显得很平滑,看着很舒服了,最主要的操作DOM结构的次数就大大减少了;

优化了页面性能,降低了内存消耗,不然你像IE这种比较老点版本的浏览器,说不定就直接给你蹦了

用书面一点的说法就是,在某个事件没有结束之前,函数不会执行,当结束之后,我们给定延时时间,然他在给定的延时时间之后再去执行这个函数,这就是防抖函数;

来看代码:

//将上面的throttle函数替换为debounce函数;
function debounce(method,time){
 var timer = null ;
 return function(){
  var context = this;
  //在函数执行的时候先清除timer定时器;
  clearTimeout(timer);
  timer = setTimeout(function(){
   method.call(context);
  },time);
 }
}

思路就是在函数执行之前,我们先清除定时器,如果函数一直执行,就会不断的去清除定时器中的方法,知道我们操作结束之后,函数才会执行;

其实书写的方式有很多,主要还是思路的问题,大家写的多了,自然就知道了;

用途

  1. 当我们做keyup像后台请求检验的时候,可以使用防抖函数,不然我们每按一次键盘就请求一次,请求太频繁,这样当我们结束按键盘的时候再去请求,请求少很多了,性能自然不用说;
  2. resize 窗口大小调整的时候,我们可以采用防抖技术也可以使用节流;
  3. mousemove 鼠标移动事件我们既可以采用防抖也可以使用节流;
  4. scroll 滚动条触发的事件,当然既可以采用防抖也可以采用节流;
  5. 连续高频发的事件都可以采用这两种方式去解决,优化页面性能;

具体的采用哪一种更较为合适,主要还是看你的业务需求,好了,本篇就到这里了,感谢大家阅读;希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
Jul 24 Javascript
jquery遍历checkbox介绍
Feb 21 Javascript
jQuery使用andSelf()来包含之前的选择集
May 19 Javascript
js获取form的方法
May 06 Javascript
javascript Promise简单学习使用方法小结
May 17 Javascript
jQGrid动态填充select下拉框的选项值(动态填充)
Nov 28 Javascript
jquery-file-upload 文件上传带进度条效果
Nov 21 jQuery
解决循环中setTimeout执行顺序的问题
Jun 20 Javascript
详解Angular中通过$location获取地址栏的参数
Aug 02 Javascript
vue中格式化时间过滤器代码实例
Apr 17 Javascript
pm2发布node配置文件ecosystem.json详解
May 15 Javascript
全面解析Vue中的$nextTick
Dec 24 Vue.js
基于jQuery实现定位导航位置效果
Nov 15 #jQuery
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 #Javascript
vuejs实现本地数据的筛选分页功能思路详解
Nov 15 #Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
Nov 15 #Javascript
实现div内部滚动条滚动到底部和顶部的代码
Nov 15 #Javascript
js 原生判断内容区域是否滚动到底部的实例代码
Nov 15 #Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
Nov 15 #Javascript
You might like
解决FastCGI 进程超过了配置的活动超时时限的问题
2013/07/03 PHP
php快速查找数据库中恶意代码的方法
2015/04/01 PHP
php微信开发之图片回复功能
2018/06/14 PHP
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
2007/02/22 Javascript
javascript拓展DOM操作 prependChild insertAfert
2010/11/17 Javascript
jQuery Ajax方法调用 Asp.Net WebService 的详细实例代码
2011/04/27 Javascript
IE事件对象(The Internet Explorer Event Object)
2012/06/27 Javascript
js数组Array sort方法使用深入分析
2013/02/21 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
2015/05/09 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
bootstrap导航、选项卡实现代码
2016/12/28 Javascript
微信小程序 数组中的push与concat的区别
2017/01/05 Javascript
layui写后台表格思路和赋值用法详解
2019/11/14 Javascript
在Vue中创建可重用的 Transition的方法
2020/06/02 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
2020/07/19 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
vue 验证两次输入的密码是否一致的方法示例
2020/09/29 Javascript
跟老齐学Python之做一个小游戏
2014/09/28 Python
python xml.etree.ElementTree遍历xml所有节点实例详解
2016/12/04 Python
Python 2.7中文显示与处理方法
2018/07/16 Python
详解Python发送email的三种方式
2018/10/18 Python
基于python实现KNN分类算法
2020/04/23 Python
python之mock模块基本使用方法详解
2019/06/27 Python
python 比较2张图片的相似度的方法示例
2019/12/18 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
Python request post上传文件常见要点
2020/11/20 Python
英国创新设计文具、卡片和礼品包装网站:Paperchase
2018/07/14 全球购物
国贸专业的职业规划范文
2014/01/23 职场文书
临床医师个人自我评价
2014/04/06 职场文书
大三学习计划书范文
2014/05/02 职场文书
办理房产过户的委托书
2014/09/14 职场文书
2016年寒假生活小结
2015/10/10 职场文书
ztree+ajax实现文件树下载功能
2021/05/18 Javascript
python套接字socket通信
2022/04/01 Python
html中两种获取标签内的值的方法
2022/06/10 HTML / CSS
Win11 Build 25179预览版发布(附更新内容+ISO官方镜像下载)
2022/08/14 数码科技