深入了解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的自定义事件代码,触发,绑定简单实例
Aug 01 Javascript
JavaScript改变CSS样式的方法汇总
May 07 Javascript
JavaScript动态改变div属性的实现方法
Jul 22 Javascript
jQuery模拟物体自由落体运动(附演示与demo源码下载)
Jan 21 Javascript
浅谈Javascript事件对象
Feb 05 Javascript
js实现多张图片延迟加载效果
Jul 17 Javascript
react-router4 嵌套路由的使用方法
Jul 24 Javascript
微信小程序基于本地缓存实现点赞功能的方法
Dec 18 Javascript
基于Vuex无法观察到值变化的解决方法
Mar 01 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
Jul 10 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
Sep 07 Javascript
ios中视频的最后一桢问题解决
May 14 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
php adodb连接mssql解决乱码问题
2009/06/12 PHP
php5.3后静态绑定用法详解
2016/11/11 PHP
php实现微信分享朋友链接功能
2019/02/18 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
window.js 主要包含了页面的一些操作
2009/12/23 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
JavaScript常用脚本汇总(二)
2015/03/04 Javascript
js改变embed标签src值的方法
2015/04/10 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
2015/05/03 Javascript
基于javascript简单实现对身份证校验
2021/01/25 Javascript
jQuery通过写入cookie实现更换网页背景的方法
2016/04/15 Javascript
ES6中Array.find()和findIndex()函数的用法详解
2017/09/16 Javascript
JavaScript中Object基础内部方法图
2018/02/05 Javascript
浅谈Vue路由快照实现思路及其问题
2018/06/07 Javascript
Vue开发之封装上传文件组件与用法示例
2019/04/25 Javascript
JS 实现发送短信验证码的“59秒后重新发送验证短信”功能
2019/08/23 Javascript
详解VUE中的插值( Interpolation)语法
2020/10/18 Javascript
vscode+gulp轻松开发小程序的完整步骤
2020/10/18 Javascript
[05:00]第二届DOTA2亚洲邀请赛主赛事第三天比赛集锦.mp4
2017/04/04 DOTA
[42:32]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第二场 10.28
2020/10/28 DOTA
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
python实现将文本转换成语音的方法
2015/05/28 Python
利用Django-environ如何区分不同环境
2018/08/26 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
python判断all函数输出结果是否为true的方法
2020/12/03 Python
护理职业应聘自荐书
2013/09/29 职场文书
生产厂长岗位职责
2014/02/21 职场文书
企业人事任命书
2014/06/05 职场文书
工地宣传标语
2014/06/18 职场文书
住房抵押登记委托书
2014/09/27 职场文书
生日宴会祝酒词
2015/08/10 职场文书
Vue3 Composition API的使用简介
2021/03/29 Vue.js
详解前端任务构建利器Gulp.js使用指南
2021/04/30 Javascript
设置IIS Express并发数
2022/07/07 Servers