深入了解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 ajax中使用jsonp的限制解决方法
Nov 22 Javascript
js解决弹窗问题实现班级跳转DIV示例
Jan 06 Javascript
从零学JSON之JSON数据结构
May 19 Javascript
jquery重复提交请求的原因浅析
May 23 Javascript
jQuery的each循环用法简单示例
Jun 12 Javascript
探讨跨域请求资源的几种方式(总结)
Dec 02 Javascript
详解前端路由实现与react-router使用姿势
Aug 07 Javascript
解析vue中的$mount
Dec 21 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
Mar 06 Javascript
小程序跳转H5页面的方法步骤
Mar 06 Javascript
Vue之封装公用变量以及实现方式
Jul 31 Javascript
利用 JavaScript 实现并发控制的示例代码
Dec 31 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
全国FM电台频率大全 - 1 北京市
2020/03/11 无线电
isset和empty的区别
2007/01/15 PHP
使用php判断浏览器的类型和语言的函数代码
2013/02/28 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
PHP新建类问题分析及解决思路
2015/11/19 PHP
php中namespace use用法实例分析
2016/01/22 PHP
php实现多维数组排序的方法示例
2017/03/23 PHP
用jquery来定位
2007/02/20 Javascript
document.open() 与 document.write()的区别
2007/08/13 Javascript
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
JS 参数传递的实际应用代码分析
2009/09/13 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
删除节点的jquery代码
2014/01/13 Javascript
JS加载器如何动态加载外部js文件
2016/05/26 Javascript
js操作XML文件的实现方法兼容IE与FireFox
2016/06/25 Javascript
JavaScript提高网站性能优化的建议(二)
2016/07/24 Javascript
jquery 实时监听输入框值变化的完美方法(必看)
2017/01/26 Javascript
原生js实现移动端触摸轮播的示例代码
2017/12/22 Javascript
从源码里了解vue中的nextTick的使用
2018/11/22 Javascript
python网络编程学习笔记(一)
2014/06/09 Python
python回调函数中使用多线程的方法
2017/12/25 Python
使用python实现快速搭建简易的FTP服务器
2018/09/12 Python
Python django框架应用中实现获取访问者ip地址示例
2019/05/17 Python
python中的协程深入理解
2019/06/10 Python
python中几种自动微分库解析
2019/08/29 Python
Python descriptor(描述符)的实现
2020/11/15 Python
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
怀旧香味蜡烛:Homesick
2019/11/02 全球购物
感恩的演讲稿
2014/05/06 职场文书
副总经理任命书
2014/06/05 职场文书
七夕活动策划方案
2014/08/16 职场文书
小学思品教学反思
2016/02/20 职场文书
spring cloud gateway中如何读取请求参数
2021/07/15 Java/Android
CSS 左边固定宽右边自适应的6种方法
2022/05/15 HTML / CSS
SpringBoot深入分析讲解监听器模式下
2022/07/15 Java/Android