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 相关文章推荐
jquery 多行滚动代码(附详细解释)
Jun 17 Javascript
jQuery选择器中含有空格的使用示例及注意事项
Aug 25 Javascript
JavaScript基础知识点归纳(推荐)
Jul 09 Javascript
vue-cli入门之项目结构分析
Apr 20 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
May 08 jQuery
JS实现的加减乘除四则运算计算器示例
Aug 09 Javascript
Vue项目分环境打包的实现步骤
Apr 02 Javascript
在vue项目中集成graphql(vue-ApolloClient)
Sep 08 Javascript
开发用到的js封装方法(20种)
Oct 12 Javascript
webpack自动打包和热更新的实现方法
Jun 24 Javascript
Vue中使用matomo进行访问流量统计的实现
Nov 05 Javascript
Openlayers3实现车辆轨迹回放功能
Sep 29 Javascript
基于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
PHP 字符截取 解决中文的截取问题,不用mb系列
2009/09/29 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
JavaScript CSS菜单功能 改进版
2008/12/20 Javascript
JavaScript 字符编码规则
2009/05/04 Javascript
几个常用的JavaScript字符串处理函数 - split()、join()、substring()和indexOf()
2009/06/02 Javascript
获取网站跟路径的javascript代码(站点及虚拟目录)
2009/10/20 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
2014/12/28 Javascript
JavaScript动态创建form表单并提交的实现方法
2015/12/10 Javascript
javascript实现简易计算器的代码
2016/05/31 Javascript
js在ie下打开对话窗口的方法小结
2016/10/24 Javascript
详解AngularJS中的表单验证(推荐)
2016/11/17 Javascript
JavaScript自定义函数实现查找两个字符串最长公共子串的方法
2016/11/24 Javascript
Jquery Easyui进度条组件Progress使用详解(8)
2020/03/26 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
2017/03/08 Javascript
jstree单选功能的实现方法
2017/06/07 Javascript
WdatePicker.js时间日期插件的使用方法
2017/07/26 Javascript
layui radio性别单选框赋值方法
2018/08/15 Javascript
12 种使用Vue 的最佳做法
2020/03/30 Javascript
js实现查询商品案例
2020/07/22 Javascript
基于python3 类的属性、方法、封装、继承实例讲解
2017/09/19 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
Python3爬楼梯算法示例
2019/03/04 Python
Python使用Pickle模块进行数据保存和读取的讲解
2019/04/09 Python
PyTorch基本数据类型(一)
2019/05/22 Python
使用Python的Turtle库绘制森林的实例
2019/12/18 Python
详解Python中的编码问题(encoding与decode、str与bytes)
2020/09/30 Python
使用HTML5 Geolocation实现一个距离追踪器
2018/04/09 HTML / CSS
优秀大学生的自我评价
2014/01/16 职场文书
如何写早恋检讨书
2014/09/10 职场文书
2014年十八届四中全会思想汇报范文
2014/10/17 职场文书
演讲开场白和结束语
2015/05/29 职场文书
2016年大学生暑假爱心支教活动策划书
2015/11/26 职场文书
浅谈Python数学建模之数据导入
2021/06/23 Python
德生TECSUN S-2000使用手册文字版
2022/05/10 无线电
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android
pnpm对npm及yarn降维打击详解
2022/08/05 Javascript