深入了解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 相关文章推荐
JQuery 解析多维的Json数据格式
Nov 02 Javascript
浅谈JavaScript函数节流
Dec 09 Javascript
JavaScript中的console.time()函数详细介绍
Dec 29 Javascript
jquery不常用方法汇总
Jul 26 Javascript
JavaScript编写带旋转+线条干扰的验证码脚本实例
May 30 Javascript
微信小程序request请求后台接口php的实例详解
Sep 20 Javascript
Angular 项目实现国际化的方法
Jan 08 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
Jul 11 Javascript
Bootstrap table表格初始化表格数据的方法
Jul 25 Javascript
快速解决angularJS中用post方法时后台拿不到值的问题
Aug 14 Javascript
jquery实现Ajax请求的几种常见方式总结
May 28 jQuery
Jquery实现获取子元素的方法分析
Aug 24 jQuery
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 神盾解密工具 ”
2014/06/20 PHP
Yii开启片段缓存的方法
2016/03/28 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
PHP Swoole异步MySQL客户端实现方法示例
2019/10/24 PHP
漂亮的widgets,支持换肤和后期开发新皮肤(2007-4-27已更新1.7alpha)
2007/04/27 Javascript
JavaScript 代码压缩工具小结
2012/02/27 Javascript
JavaScript高级程序设计 读书笔记之十一 内置对象Global
2012/03/07 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
jQuery 获取和设置select下拉框的值实现代码
2013/11/08 Javascript
jquery-syntax动态语法着色示例代码
2014/05/14 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
jQuery+正则+文本框只能输入数字的实现方法
2016/10/07 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
2018/01/23 Javascript
快速解决bootstrap下拉菜单无法隐藏的问题
2018/08/10 Javascript
Angular7.2.7路由使用初体验
2019/03/01 Javascript
vant IndexBar实现的城市列表的示例代码
2019/11/20 Javascript
[45:10]NB vs Liquid Supermajor小组赛 A组胜者组决赛 BO3 第二场 6.2
2018/06/04 DOTA
[01:21:58]守擂赛DOTA2第一周决赛
2020/04/22 DOTA
python读取与写入csv格式文件的示例代码
2017/12/16 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
pip安装时ReadTimeoutError的解决方法
2018/06/12 Python
解决Python print输出不换行没空格的问题
2018/11/14 Python
python ddt数据驱动最简实例代码
2019/02/22 Python
python实现tail -f 功能
2020/01/17 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
python3检查字典传入函数键是否齐全的实例
2020/06/05 Python
Python sorted对list和dict排序
2020/06/09 Python
用html5的canvas画布绘制贝塞尔曲线完整代码
2013/08/14 HTML / CSS
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
趣味比赛活动方案
2014/02/15 职场文书
公务员考察材料范文
2014/12/23 职场文书
颐和园导游词400字
2015/01/30 职场文书
详解Java线程池是如何重复利用空闲线程的
2021/06/26 Java/Android
清空 Oracle 安装记录并重新安装
2022/04/26 Oracle