深入了解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 相关文章推荐
js showModalDialog参数的使用详解
Jan 07 Javascript
jQuery实现友好的轮播图片特效
Jan 12 Javascript
jquery实现页面虚拟键盘特效
Aug 08 Javascript
深入理解js函数的作用域与this指向
May 28 Javascript
Bootstrap实现导航栏的2种方式
Nov 28 Javascript
js实现一个可以兼容PC端和移动端的div拖动效果实例
Dec 09 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
Jun 16 Javascript
Vue学习笔记之表单输入控件绑定
Sep 05 Javascript
详解RequireJs官方使用教程
Oct 31 Javascript
开发Vue树形组件的示例代码
Dec 21 Javascript
微信小程序云开发之使用云数据库
May 17 Javascript
JavaScript this指向相关原理及实例解析
Jul 10 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中使用XML
2006/10/09 PHP
php面向对象全攻略 (十四) php5接口技术
2009/09/30 PHP
Session 失效的原因汇总及解决丢失办法
2015/09/30 PHP
PHP实现的多进程控制demo示例
2019/07/22 PHP
用JQUERY增删元素的代码
2012/02/14 Javascript
jquery 无限级联菜单案例分享
2013/03/26 Javascript
AngularJS入门教程之学习环境搭建
2014/12/06 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
JQuery实现动态适时改变字体颜色的方法
2015/03/10 Javascript
JS实现的数组全排列输出算法
2015/03/19 Javascript
第三章之Bootstrap 表格与按钮功能
2016/04/25 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
2016/11/22 Javascript
js实现自定义路由
2017/02/04 Javascript
AngularJS学习笔记之表单验证功能实例详解
2017/07/06 Javascript
JQ图片文件上传之前预览功能的简单实例(分享)
2017/11/12 Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
2018/05/16 Javascript
微信小程序使用swiper组件实现层叠轮播图
2018/11/04 Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
2019/02/18 Javascript
微信小程序实现滑动翻页效果(完整代码)
2019/12/06 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
vscode+gulp轻松开发小程序的完整步骤
2020/10/18 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
vue-quill-editor插入图片路径太长问题解决方法
2021/01/08 Vue.js
python修改操作系统时间的方法
2015/05/18 Python
Python3中类、模块、错误与异常、文件的简易教程
2017/11/20 Python
Python实现中一次读取多个值的方法
2018/04/22 Python
利用PyCharm Profile分析异步爬虫效率详解
2019/05/08 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
解决HTML5中滚动到底部的事件问题
2019/08/22 HTML / CSS
DC Shoes俄罗斯官网:美国滑板鞋和服饰品牌
2020/08/19 全球购物
委托证明的格式
2014/01/10 职场文书
股指期货心得体会
2014/09/10 职场文书
税务干部群众路线教育实践活动对照检查材料
2014/09/20 职场文书
详解JavaScript的计时器和按钮效果设置
2022/02/18 Javascript
vue 给数组添加新对象并赋值
2022/04/20 Vue.js