深入了解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写的日历类(基于pj)
Dec 28 Javascript
解析javascript系统错误:-1072896658的解决办法
Jul 08 Javascript
JavaScript使用yield模拟多线程的方法
Mar 19 Javascript
用Move.js配合创建CSS3动画的入门指引
Jul 22 Javascript
AngularJS实现表单手动验证和表单自动验证
Dec 09 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
解析Javascript单例模式概念与实例
Dec 05 Javascript
jQuery实现火车票买票城市选择切换功能
Sep 15 jQuery
基于jquery.page.js实现分页效果
Jan 01 jQuery
JS实现为动态添加的元素增加事件功能示例【基于事件委托】
Mar 21 Javascript
JS浏览器BOM常见操作实例详解
Apr 27 Javascript
JavaScript实现简单日历效果
Sep 11 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
php封装的单文件(图片)上传类完整实例
2016/10/18 PHP
thinkPHP中session()方法用法详解
2016/12/08 PHP
javascript改变position值实现菜单滚动至顶部后固定
2013/01/18 Javascript
jQuery学习笔记(1)--用jQuery实现异步通信(用json传值)具体思路
2013/04/08 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
JS操作CSS随机改变网页背景实现思路
2014/03/10 Javascript
js实现类似于add(1)(2)(3)调用方式的方法
2015/03/04 Javascript
javascript+HTML5自定义元素播放焦点图动画
2016/02/21 Javascript
jQuery判断浏览器并动态调整select宽度的方法
2016/03/02 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
原生js实现选项卡功能
2017/03/08 Javascript
js+html5生成自动排列对话框实例
2017/10/09 Javascript
Vue中自定义全局组件的实现方法
2017/12/08 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
详解关于element el-button使用$attrs的一个注意要点
2018/11/09 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
通过JS运行机制的角度说说作用域
2019/03/12 Javascript
Node.js 深度调试方法解析
2020/07/28 Javascript
vue离开当前页面触发的函数代码
2020/09/01 Javascript
Vue实现多页签组件
2021/01/14 Vue.js
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
2016/08/30 Python
python监控文件并且发送告警邮件
2018/06/21 Python
python3实现多线程聊天室
2018/12/12 Python
Django框架设置cookies与获取cookies操作详解
2019/05/27 Python
详解python 中in 的 用法
2019/12/12 Python
Python操作Excel把数据分给sheet
2020/05/20 Python
通过实例了解python__slots__使用方法
2020/09/14 Python
python 检测nginx服务邮件报警的脚本
2020/12/31 Python
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
英语生日邀请函
2014/01/23 职场文书
乡镇总工会学雷锋活动总结
2014/03/01 职场文书
结对共建工作方案
2014/06/02 职场文书
个人查摆剖析材料
2014/10/04 职场文书
2015年党员干部承诺书
2015/01/21 职场文书
2015年师德师风自我评价范文
2015/03/05 职场文书
Lakehouse数据湖并发控制陷阱分析
2022/03/31 Oracle