深入了解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 判断字符串是否为数字的简单方法
Jul 25 Javascript
点击下载链接 弹出页面实现代码
Oct 01 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
Jan 13 Javascript
基于jquery实现轮播特效
Apr 22 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
Aug 01 Javascript
js获取一组日期中最近连续的天数
May 25 Javascript
Angular4编程之表单响应功能示例
Dec 13 Javascript
小程序实现选择题选择效果
Nov 04 Javascript
原生JS实现图片懒加载之页面性能优化
Apr 26 Javascript
webpack4 SplitChunks实现代码分隔详解
May 23 Javascript
简单了解vue.js数组的常用操作
Jun 17 Javascript
vue 清空input标签 中file的值操作
Jul 21 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
《APMServ 5.1.2》使用图解
2006/10/23 PHP
mysql 中InnoDB和MyISAM的区别分析小结
2008/04/15 PHP
php中$this->含义分析
2009/11/29 PHP
PHP调用Twitter的RSS的实现代码
2010/03/10 PHP
解析strtr函数的效率问题
2013/06/26 PHP
PHP Callable强制指定回调类型的方法
2016/08/30 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
延时重复执行函数 lLoopRun.js
2007/05/08 Javascript
javascript multibox 全选
2009/03/22 Javascript
JS 图片缩放效果代码
2010/06/09 Javascript
JS实现简单的Canvas画图实例
2013/07/04 Javascript
jQuery选择id属性带有点符号元素的方法
2015/03/17 Javascript
关于JavaScript的变量的数据类型的判断方法
2015/08/14 Javascript
JavaScript实现分页效果
2017/03/28 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
2017/04/21 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
2017/05/03 Javascript
vue引入新版 vue-awesome-swiper插件填坑问题
2018/01/25 Javascript
深入浅析Vue.js计算属性和侦听器
2018/05/05 Javascript
京东优选小程序的实现代码示例
2020/02/25 Javascript
浅谈Vue static 静态资源路径 和 style问题
2020/11/07 Javascript
Python urllib模块urlopen()与urlretrieve()详解
2013/11/01 Python
python 转换 Javascript %u 字符串为python unicode的代码
2016/09/06 Python
python实现隐马尔科夫模型HMM
2018/03/25 Python
python提取图像的名字*.jpg到txt文本的方法
2018/05/10 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
树莓派3 搭建 django 服务器的实例
2019/08/29 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
2020/03/30 Python
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
如果Session Bean得Remove方法一直都不被调用会怎么样
2012/07/14 面试题
优秀演讲稿范文
2013/12/29 职场文书
小学生国庆65周年演讲稿范文(2篇)
2014/09/21 职场文书
向国旗敬礼活动总结
2014/09/27 职场文书
运动会200米广播稿
2015/08/19 职场文书
2016优秀教师先进个人事迹材料
2016/02/25 职场文书
Mysql 如何批量插入数据
2021/04/06 MySQL