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 相关文章推荐
动态加载js的几种方法
Oct 23 Javascript
浅谈Javascript中的Function与Object
Jan 26 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
Aug 29 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
Sep 13 Javascript
D3.js实现文本的换行详解
Oct 14 Javascript
js实现4个方向滚动的球
Mar 06 Javascript
react-navigation之动态修改title的内容
Sep 26 Javascript
JS闭包原理与应用经典示例
Dec 20 Javascript
echarts实现词云自定义形状的示例代码
Feb 20 Javascript
react 中父组件与子组件双向绑定问题
May 20 Javascript
vue组件库的在线主题编辑器的实现思路
Apr 03 Javascript
如何利用vue实现波谱拟合详解
Nov 05 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
如何在PHP中使用Oracle数据库(6)
2006/10/09 PHP
Blitz templates 最快的PHP模板引擎
2010/04/06 PHP
PHP调用wsdl文件类型的接口代码分享
2014/11/19 PHP
THinkPHP获取客户端IP与IP地址查询的方法
2016/11/14 PHP
javascript addBookmark 加入收藏 多浏览器兼容
2009/08/15 Javascript
Javascript将string类型转换int类型
2010/12/09 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
JavaScript生成随机数的4种自定义函数分享
2015/02/28 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
angular.bind使用心得
2015/10/26 Javascript
jQuery animate easing使用方法图文详解
2016/06/17 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
JS中实现函数return多个返回值的实例
2017/02/21 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
2018/10/26 jQuery
详解vue 在移动端体验上的优化解决方案
2019/05/20 Javascript
浅谈JS中几种轻松处理'this'指向方式
2019/09/16 Javascript
webpack 处理CSS资源的实现
2019/09/27 Javascript
Pyqt5 基本界面组件之inputDialog的使用
2019/06/25 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
Python正则表达式急速入门(小结)
2019/12/16 Python
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
资料员的岗位职责
2013/11/20 职场文书
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
优秀导游先进事迹材料
2014/01/25 职场文书
幼儿园大班教学反思
2014/02/10 职场文书
2014年预备党员学习两会心得体会
2014/03/17 职场文书
青春奉献演讲稿
2014/05/08 职场文书
滞留工资返还协议书
2014/10/19 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
村党组织公开承诺书
2015/04/30 职场文书
什么是求职信?求职信应包含哪些内容?
2019/08/14 职场文书
Python办公自动化之Excel(中)
2021/05/24 Python
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android