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 Flash/MP3/Video多媒体插件
Jan 18 Javascript
基于jquery的滚动新闻列表
Jun 19 Javascript
javascript各浏览器中option元素的表现差异
Apr 07 Javascript
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
Jul 31 Javascript
js图片跟随鼠标移动代码
Nov 26 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
Dec 28 Javascript
基于JavaScript实现瀑布流布局
Aug 15 Javascript
vue-swiper的使用教程
Aug 30 Javascript
Node.js原生api搭建web服务器的方法步骤
Feb 15 Javascript
vue 实现v-for循环回来的数据动态绑定id
Nov 07 Javascript
基于VUE实现判断设备是PC还是移动端
Jul 03 Javascript
深入了解Vue.js 混入(mixins)
Jul 23 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将数据库中的电话号码读取出来并生成图片
2008/08/31 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
调试WordPress中定时任务的相关PHP脚本示例
2015/12/10 PHP
PHP HTTP 认证实例详解
2016/11/03 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
jquery 插件 人性化的消息显示
2008/01/21 Javascript
javascript 表单验证常见正则
2009/09/28 Javascript
理解 JavaScript 预解析
2009/10/25 Javascript
JavaScript中String和StringBuffer的速度之争
2010/04/01 Javascript
ASP.NET jQuery 实例13 原创jQuery文本框字符限制插件-TextArea Counter
2012/02/03 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
对于Form表单reset方法的新认识
2014/03/05 Javascript
一个很有趣3D球状标签云兼容IE8
2014/08/22 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
javascript将中国数字格式转换成欧式数字格式的简单实例
2016/08/02 Javascript
JS基于面向对象实现的多个倒计时器功能示例
2017/02/28 Javascript
微信小程序五星评分效果实现代码
2017/04/06 Javascript
AngularJS实现根据不同条件显示不同控件
2017/04/20 Javascript
详解Vue用axios发送post请求自动set cookie
2017/05/10 Javascript
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
原生JS上传大文件显示进度条 php上传文件代码
2020/03/27 Javascript
JavaScript对象拷贝与赋值操作实例分析
2018/12/10 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
js常用方法、检查是否有特殊字符串、倒序截取字符串操作完整示例
2020/01/26 Javascript
vue实现选中效果
2020/10/07 Javascript
在Python的Django框架中显示对象子集的方法
2015/07/21 Python
使用Python的Dataframe取两列时间值相差一年的所有行方法
2018/07/10 Python
Django中URL的参数传递的实现
2019/08/04 Python
借助Paramiko通过Python实现linux远程登陆及sftp的操作
2020/03/16 Python
美国汽车轮胎和轮毂销售网站:Tire Rack
2018/01/11 全球购物
Piercing Pagoda官网:耳环、戒指、项链、手链等
2020/09/28 全球购物
求职自荐书范文
2013/12/04 职场文书
收银员的岗位职责范本
2014/02/04 职场文书
企业开业庆典答谢词
2015/01/20 职场文书
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python