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复制文本框和表格的代码
Apr 01 Javascript
使用JS取得焦点(focus)元素代码
Mar 22 Javascript
jquery取子节点及当前节点属性值的方法
Sep 09 Javascript
jquery插件autocomplete用法示例
Jul 01 Javascript
AngularJS  $modal弹出框实例代码
Aug 24 Javascript
vue一步步实现alert功能
Jul 05 Javascript
详解ES6之用let声明变量以及let loop机制
Jul 15 Javascript
vue绑定的点击事件阻止冒泡的实例
Feb 08 Javascript
使用vue-cli导入Element UI组件的方法
May 16 Javascript
MVVM 双向绑定的实现代码
Jun 21 Javascript
对angular 监控数据模型变化的事件方法$watch详解
Oct 09 Javascript
构建Vue大型应用的10个最佳实践(小结)
Nov 07 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中实现进程间通讯
2006/10/09 PHP
PHP中register_globals参数为OFF和ON的区别(register_globals 使用详解)
2012/02/05 PHP
PHP JS Ip地址及域名格式检测代码
2013/09/27 PHP
php中的四舍五入函数代码(floor函数、ceil函数、round与intval)
2014/07/14 PHP
Linux下源码包安装Swoole及基本使用操作图文详解
2019/04/02 PHP
在Laravel中使用GuzzleHttp调用第三方服务的API接口代码
2019/10/15 PHP
document.all还是document.getElementsByName?
2006/07/21 Javascript
很棒的学习jQuery的12个网站推荐
2011/04/28 Javascript
最佳的addEvent事件绑定是怎样诞生的
2011/10/24 Javascript
javascript对中文按照拼音排序代码
2014/08/20 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
JavaScript对象之深度克隆介绍
2014/12/08 Javascript
JavaScript之Object类型介绍
2015/04/01 Javascript
javascript添加前置0(补零)的几种方法
2017/01/05 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
使用Python中的cookielib模拟登录网站
2015/04/09 Python
python logging日志模块的详解
2017/10/29 Python
Python登录并获取CSDN博客所有文章列表代码实例
2017/12/28 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
python机器学习库scikit-learn:SVR的基本应用
2019/06/26 Python
python3中类的继承以及self和super的区别详解
2019/06/26 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
python笔记之mean()函数实现求取均值的功能代码
2019/07/05 Python
tensorflow使用指定gpu的方法
2020/02/04 Python
如何使用python的ctypes调用医保中心的dll动态库下载医保中心的账单
2020/05/24 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
Booking.com缤客中国:全球酒店在线预订网站
2020/05/03 全球购物
STP协议的主要用途是什么?为什么要用STP
2012/12/20 面试题
法律专业应届生自荐信范文
2014/01/06 职场文书
个人承诺书怎么写
2014/05/24 职场文书
个人债务授权委托书
2014/10/17 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
docker compose 部署 golang 的 Athens 私有代理问题
2022/04/28 Servers