深入了解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 28 Javascript
js修改input的type属性问题探讨
Oct 12 Javascript
JQuery自动触发事件的方法
Jun 13 Javascript
js+ajax实现获取文件大小的方法
Dec 08 Javascript
js中最容易被忽视的事件问题大总结
May 15 Javascript
跨域请求的完美解决方法(JSONP, CORS)
Jun 12 Javascript
jQuery插件Echarts实现的渐变色柱状图
Mar 23 jQuery
使用JSON格式提交数据到服务端的实例代码
Apr 01 Javascript
Angular angular-file-upload文件上传的示例代码
Aug 23 Javascript
js JSON.stringify()基础详解
Jun 19 Javascript
antd的select下拉框因为数据量太大造成卡顿的解决方式
Oct 31 Javascript
vue实现移动端div拖动效果
Mar 03 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
纯php打造的tab选项卡效果代码(不用js)
2010/12/29 PHP
PHP 命令行参数详解及应用
2011/05/18 PHP
Thinkphp模板中截取字符串函数简介
2014/06/17 PHP
ThinkPHP之R方法实例详解
2014/06/20 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
PDO::exec讲解
2019/01/28 PHP
javascript 回调函数详解
2014/11/11 Javascript
JavaScript语言对Unicode字符集的支持详解
2014/12/30 Javascript
javascript实现确定和取消提示框效果
2015/07/10 Javascript
基于JS实现Android,iOS一个手势动画效果
2016/04/27 Javascript
JavaScript 监控微信浏览器且自带返回按钮时间
2016/11/27 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
2017/03/03 Javascript
详解vue模拟加载更多功能(数据追加)
2017/06/23 Javascript
分享Bootstrap简单表格、表单、登录页面
2017/08/04 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
2019/09/05 Javascript
在Python中操作字典之update()方法的使用
2015/05/22 Python
批处理与python代码混合编程的方法
2016/05/19 Python
python开发环境PyScripter中文乱码问题解决方案
2016/09/11 Python
python 不以科学计数法输出的方法
2018/07/16 Python
Python使用post及get方式提交数据的实例
2019/01/24 Python
pymongo中group by的操作方法教程
2019/03/22 Python
使用Python操作ArangoDB的方法步骤
2020/02/02 Python
Python telnet登陆功能实现代码
2020/04/16 Python
matlab中二维插值函数interp2的使用详解
2020/04/22 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
Canvas 文本填充线性渐变的使用详解
2020/06/22 HTML / CSS
在校生党员自我评价
2013/09/25 职场文书
生物化工专业个人自荐信
2013/09/26 职场文书
运动会广播稿20字
2014/02/18 职场文书
中华魂演讲稿
2014/05/13 职场文书
珍惜资源的建议书
2014/08/26 职场文书
2014年师德师风自我剖析材料
2014/09/27 职场文书
专题组织生活会思想汇报
2014/10/01 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
七年级作文之我的梦想
2019/10/16 职场文书
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python