深入了解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中运用闭包和自执行函数解决大量的全局变量问题
Dec 30 Javascript
JavaScript 选中文字并响应获取的实现代码
Aug 28 Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
Apr 15 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
Nov 25 Javascript
基于jQuery实现左右图片轮播(原理通用)
Dec 24 Javascript
微信小程序 实现点击添加移除class
Jun 12 Javascript
微信小程序自定义组件
Aug 16 Javascript
JS使用tofixed与round处理数据四舍五入的区别
Oct 25 Javascript
nginx部署访问vue-cli搭建的项目的方法
Feb 12 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
基于vue通用表单解决方案的思考与分析
Mar 16 Javascript
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
Apr 06 Vue.js
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
中国的第一台收音机
2021/03/01 无线电
全新Mac配置PHP开发环境教程
2016/02/03 PHP
PHP数据库操作四:mongodb用法分析
2017/08/16 PHP
麦鸡的TAB切换功能结合了javascript和css
2007/12/17 Javascript
jquery限定文本框只能输入数字即整数和小数
2013/11/29 Javascript
jQuery修改li下的样式以及li下的img的src的值的方法
2014/11/02 Javascript
JavaScript学习笔记之Function对象
2015/01/22 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
JavaScript和JQuery获取DIV值的方法示例
2017/03/07 Javascript
BootStrap表单控件之文本域textarea
2017/05/23 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
2018/07/11 Javascript
微信小程序实现保存图片到相册功能
2018/11/30 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
vue.js 2.0实现简单分页效果
2019/07/29 Javascript
javascript 构建模块化开发过程解析
2019/09/11 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
Vue实现点击当前行变色
2020/12/14 Vue.js
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
Python中的localtime()方法使用详解
2015/05/22 Python
自动化Nginx服务器的反向代理的配置方法
2015/06/28 Python
python绘制简单折线图代码示例
2017/12/19 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
tensorflow实现在函数中用tf.Print输出中间值
2020/01/21 Python
应届生服务员求职信
2013/10/31 职场文书
网站美工岗位职责
2014/04/02 职场文书
授权委托书范本
2014/04/03 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
关于十八大的演讲稿
2014/09/15 职场文书
2014年就业工作总结
2014/11/26 职场文书
2015年党性分析材料
2014/12/19 职场文书
感恩教育观后感
2015/06/17 职场文书
师德师风心得体会(2016精选篇)
2016/01/12 职场文书
python批量更改目录名/文件名的方法
2021/04/18 Python
Python 如何实现文件自动去重
2021/06/02 Python
利用js实现简单开关灯代码
2021/11/23 Javascript
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS