深入了解JavaScript 防抖和节流


Posted in Javascript onSeptember 12, 2019

概述

说明

在项目过程中,经常会遇到一个按钮被多次点击并且多次调用对应处理函数的问题,而往往我们只需去调用一次处理函数即可。有时也会遇到需要在某一规则内有规律的去触发对应的处理函数,所以就需要使用到函数防抖与函数节流来帮助我们实现我们想要的结果以及避免不必要的问题产生。

函数防抖(debounce)

定义:当持续触发事件时(如连续点击按钮多此),一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,有一次触发了事件,就重新开始延时。

原理:维护一个计时器,规定在延时时间后触发函数,但是在延时时间内再次被触发的话,就取消之前的计时器而重新设置,这样就能够保证只有最后一次操作被触发。即将所有操作合并为一个操作进行,并且只有最后一次操作是有效操作。

函数节流(throttle)

定义:当持续触发事件时,保证一定时间段内只调用一次事件处理函数,按照一定的规律在某个时间间隔内去处理函数。

原理:原理是通过判断是否达到一定时间来触发函数,使得一定时间内只触发一次函数。

代码

函数防抖

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

每次触发事件时都取消之前的延时调用方法

function debounce(fn) {
  let timeout = null; // 创建一个标记用来存放定时器的返回值
  return function () {
  clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
  timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
    fn.apply(this, arguments);
  }, 500);
  };
}
function sayHi() {
  console.log('防抖成功');
}

var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi)); // 防抖

函数节流

高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

每次触发事件时都判断当前是否有等待执行的延时函数

function throttle(fn) {
  let canRun = true; // 通过闭包保存一个标记
  return function () {
  if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
  canRun = false; // 立即设置为false
  setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
    fn.apply(this, arguments);
    // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
    canRun = true;
  }, 500);
  };
}
function sayHi(e) {
  console.log(e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript字典探测用户名工具
Oct 05 Javascript
firefox 和 ie 事件处理的细节,研究,再研究 书写同时兼容ie和ff的事件处理代码
Apr 12 Javascript
关于用Jquery的height()、width()计算动态插入的IMG标签的宽高的问题
Dec 08 Javascript
jQuery获取文本节点之 text()/val()/html() 方法区别
Mar 01 Javascript
Javascript中的匿名函数与封装介绍
Mar 15 Javascript
jquery实现简单的表单验证
Nov 17 Javascript
javascript获取wx.config内部字段解决微信分享
Mar 09 Javascript
D3.js实现折线图的方法详解
Sep 21 Javascript
jquery.zclip轻量级复制失效问题
Jan 08 Javascript
很棒的一组js图片轮播特效
Jan 12 Javascript
基于Vue2x的图片预览插件的示例代码
May 14 Javascript
js实现无限瀑布流实例方法
Sep 16 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
Sep 12 #Javascript
使用layer.msg 时间设置不起作用的解决方法
Sep 12 #Javascript
浅谈bootstrap layer.open中end的使用方法
Sep 12 #Javascript
layer iframe 设置关闭按钮的方法
Sep 12 #Javascript
改变layer confirm弹窗按钮的颜色方法
Sep 12 #Javascript
layer提示框添加多个按钮选择的实例
Sep 12 #Javascript
记录vue做微信自定义分享的一些问题
Sep 12 #Javascript
You might like
SONY SRF-M100的电路分析
2021/03/02 无线电
PHP正则+Snoopy抓取框架实现的抓取淘宝店信誉功能实例
2017/05/17 PHP
php抽象方法和普通方法的区别点总结
2019/10/13 PHP
jquery photoFrame 图片边框美化显示插件
2010/06/28 Javascript
JQuery获取浏览器窗口内容部分高度的代码
2012/02/24 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
node.js中的buffer.toJSON方法使用说明
2014/12/14 Javascript
jquery通过closest选择器修改上级元素的方法
2015/03/17 Javascript
JavaScript使用shift方法移除素组第一个元素实例分析
2015/04/06 Javascript
JavaScript实现瀑布流以及加载效果
2017/02/11 Javascript
详解JS数组Reduce()方法详解及高级技巧
2017/08/18 Javascript
jQuery自动或手动图片切换效果
2017/10/11 jQuery
javascript深拷贝、浅拷贝和循环引用深入理解
2018/05/27 Javascript
小程序实现抽奖动画
2020/04/16 Javascript
JS三级联动代码格式实例详解
2019/12/30 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
2020/10/18 Javascript
[01:21:36]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python实现网站文件的全备份和差异备份
2014/11/30 Python
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
利用python模拟实现POST请求提交图片的方法
2017/07/25 Python
使用python编写监听端
2018/04/12 Python
解决Python pandas df 写入excel 出现的问题
2018/07/04 Python
Python 如何提高元组的可读性
2019/08/26 Python
Matplotlib使用字符串代替变量绘制散点图的方法
2020/02/17 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
python对execl 处理操作代码
2020/06/22 Python
中国京东和泰国中央集团合资的网站:JD CENTRAL
2020/08/22 全球购物
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
市场部规章制度
2014/01/24 职场文书
借款协议书范本
2014/04/22 职场文书
工作推荐信范文
2014/05/10 职场文书
整改通知书格式
2015/04/22 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP
用python基于appium模块开发一个自动收取能量的小助手
2021/09/25 Python