深入了解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 Lightbox 图片展示插件使用说明
Apr 25 Javascript
js动画(animate)简单引擎代码示例
Dec 04 Javascript
jQuery+HTML5美女瀑布流布局实现方法
Sep 21 Javascript
js css实现垂直方向自适应的三角提示菜单
Jun 26 Javascript
bootstrap模态框垂直居中效果
Dec 03 Javascript
Angular.js组件之input mask对input输入进行格式化详解
Jul 10 Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
Jan 29 jQuery
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
Apr 08 Javascript
JS实现基本的网页计算器功能示例
Jan 16 Javascript
对vuex中store和$store的区别说明
Jul 24 Javascript
vue 使用post/get 下载导出文件操作
Aug 07 Javascript
详解Vue的sync修饰符
May 15 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之curl实现http与https请求的方法
2014/10/21 PHP
zen cart实现订单中增加paypal中预留电话的方法
2016/07/12 PHP
php PDO判断连接是否可用的实现方法
2017/04/03 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
PHP过滤器 filter_has_var() 函数用法实例分析
2020/04/23 PHP
解析JavaScript中instanceof对于不同的构造器或许都返回true
2013/12/03 Javascript
基于jquery实现简单的分页控件
2016/03/17 Javascript
jQuery unbind 删除绑定事件详解
2016/05/24 Javascript
javascript事件处理模型实例说明
2016/05/31 Javascript
jQuery插件实现图片轮播特效
2016/06/16 Javascript
详解用webpack2.0构建vue2.0超详细精简版
2017/04/05 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
JS中常用的消息框总结
2018/02/24 Javascript
详解vue-router数据加载与缓存使用总结
2018/10/29 Javascript
jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析
2019/03/06 jQuery
图解javascript作用域链
2019/05/27 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
谈谈JavaScript中的垃圾回收机制
2020/09/17 Javascript
python smtplib模块发送SSL/TLS安全邮件实例
2015/04/08 Python
python对数组进行反转的方法
2015/05/20 Python
Python实现的维尼吉亚密码算法示例
2018/04/12 Python
Python如何实现后端自定义认证并实现多条件登陆
2020/06/22 Python
python 带时区的日期格式化操作
2020/10/23 Python
澳大利亚女装精品店:Alannah Hill
2020/07/29 全球购物
下面这个程序执行后会有什么错误或者效果
2014/11/03 面试题
简述安装Slackware Linux系统的过程
2012/01/12 面试题
摄影实习自我鉴定
2013/09/20 职场文书
业务总经理岗位职责
2014/02/03 职场文书
媒矿安全生产承诺书
2014/05/23 职场文书
片区教研活动总结
2014/07/02 职场文书
单位考核聘任报告
2015/03/02 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers
Oracle删除归档日志及添加定时任务
2022/06/28 Oracle