深入了解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 文件传参及处理技巧分析
May 13 Javascript
JQuery下的Live方法和$.browser方法使用代码
Jun 02 Javascript
js调用AJAX时Get和post的乱码解决方法
Jun 04 Javascript
仿新浪微博登陆邮箱提示效果的js代码
Aug 02 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
Nov 25 Javascript
jQuery实现自定义事件的方法
Apr 17 Javascript
JavaScript中setFullYear()方法的使用详解
Jun 11 Javascript
js获取及修改网页背景色和字体色的方法
Dec 29 Javascript
Angular实现较为复杂的表格过滤,删除功能示例
Dec 23 Javascript
Vue+jquery实现表格指定列的文字收缩的示例代码
Jan 09 jQuery
vue指令v-html使用过滤器filters功能实例
Oct 25 Javascript
vue单文件组件无法获取$refs的问题
Jun 24 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
PHP5 安装方法
2006/10/09 PHP
php 字符转义 注意事项
2009/05/27 PHP
PHP实现路由映射到指定控制器
2016/08/13 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
2020/01/04 PHP
fix-ie5.js扩展在IE5下不能使用的几个方法
2007/08/20 Javascript
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
js中的eventType事件及其浏览器支持性介绍
2013/11/29 Javascript
JavaScript的21条基本知识点
2014/03/04 Javascript
jQuery中使用animate自定义动画的方法
2016/05/29 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
2016/06/25 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
AngularJS基础 ng-srcset 指令简单示例
2016/08/03 Javascript
AngularJs directive详解及示例代码
2016/09/01 Javascript
textarea 在浏览器中固定大小和禁止拖动的实现方法
2016/12/03 Javascript
Canvas 制作动态进度加载水球详解及实例代码
2016/12/09 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
jQuery实现checkbox的简单操作
2017/11/18 jQuery
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
jQuery实现的简单歌词滚动功能示例
2019/01/07 jQuery
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
2019/01/29 Javascript
vue3.0中友好使用antdv示例详解
2021/01/05 Vue.js
python实现simhash算法实例
2014/04/25 Python
使用pdb模块调试Python程序实例
2015/06/02 Python
利用Python生成文件md5校验值函数的方法
2017/01/10 Python
Python访问MongoDB,并且转换成Dataframe的方法
2018/10/15 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
使用python的turtle绘画滑稽脸实例
2019/11/21 Python
如何在 Django 模板中输出 "{{"
2020/01/24 Python
Python Selenium截图功能实现代码
2020/04/26 Python
在Keras中CNN联合LSTM进行分类实例
2020/06/29 Python
Jdbc数据访问技术面试题
2012/03/30 面试题
环境建设实施方案
2014/03/14 职场文书
妇女工作先进事迹
2014/08/17 职场文书
运动会开幕词
2015/01/28 职场文书
2016猴年春节问候语
2015/11/11 职场文书