防抖与节流(详解)

您所在的位置:网站首页 防抖函数封装设计 防抖与节流(详解)

防抖与节流(详解)

2023-07-10 20:23| 来源: 网络整理| 查看: 265

防抖

我们可以通过一幅图来认识这个过程 在这里插入图片描述

当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;当事件密集触发时,函数的触发会被频繁的推迟;只有等待了一段时间也没有事件触发,才会真正的执行响应函数;

应用场景

搜索框输入数据,触发事件频繁的点击按钮监听屏幕滚动事件用户窗口的resize事件

防抖的意义:只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数;

undercore实现

DOCTYPE html> Document 按钮 // 1.获取input元素 const inputEl = document.querySelector("input") // 2.监听input元素的输入 // let counter = 1 // inputEl.oninput = function() { // console.log(`发送网络请求${counter++}:`, this.value) // } // 3.防抖处理代码 let counter = 1 inputEl.oninput = _.debounce(function() { console.log(`发送网络请求${counter++}:`, this.value) }, 3000) 防抖基本功能实现:可以实现防抖效果

优化一:优化参数和this指向 优化二:优化取消操作(增加取消功能) 优化三:优化立即执行效果(第一次立即执行) 优化四:优化返回值

基本实现: const hyDebounce = function (fn,delay){ //1.第一次触发的timer let timer = null //2.触发执行后的函数 const _debounce = function(...args){ //如果再次触发,取消上一次的事件 if (timer) clearTimeout(timer) //延迟执行对应的回调函数 timer = setTimeout(()=>{ fn() //执行完函数后timer置为null timer = null },delay) } //返回函数(闭包) return _debounce } this优化 function hydebounce(fn, delay) { // 1.用于记录上一次事件触发的timer let timer = null // 2.触发事件时执行的函数 const _debounce = function(...args) { // 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件 if (timer) clearTimeout(timer) // 2.2.延迟去执行对应的fn函数(传入的回调函数) timer = setTimeout(() => { fn.apply(this, args) timer = null // 执行过函数之后, 将timer重新置null }, delay); } // 返回一个新的函数 return _debounce } 取消功能 const hyDebounce = function (fn,delay){ //1.第一次触发的timer let timer = null //2.触发执行后的函数 const _debounce = function(...args){ //如果再次触发,取消上一次的事件 if (timer) clearTimeout(timer) //延迟执行对应的回调函数 timer = setTimeout(()=>{ //绑定this fn.apply(this,args) //执行完函数后timer置为null timer = null },delay) } //取消函数 _debounce.cancel = function (){ if(timer) clearTimeout(timer) timer = null } //返回函数(闭包) return _debounce } 立即执行功能 // 原则: 一个函数进行做一件事情, 一个变量也用于记录一种状态 const hyDebounce = function (fn,delay,immediate = true){ //1.第一次触发的timer let timer = null let isInvoke = false //2.触发执行后的函数 const _debounce = function(...args){ //如果再次触发,取消上一次的事件 if (timer) clearTimeout(timer) //第一次是否不需要延迟 if(immediate && !isInvoke){ fn.apply(this,args) isInvoke = true return } //延迟执行对应的回调函数 timer = setTimeout(()=>{ //绑定this fn.apply(this,args) //执行完函数后timer置为null timer = null isInvoke = false },delay) } //取消函数 _debounce.cancel = function (){ if(timer) clearTimeout(timer) timer = null isInvoke = false } //返回函数(闭包) return _debounce 获取返回值 const hyDebounce = function (fn,delay,immediate = true){ //1.第一次触发的timer let timer = null let isInvoke = false //2.触发执行后的函数 const _debounce = function(...args){ return new Promise((resolve,reject)=>{ try { //如果再次触发,取消上一次的事件 if (timer) clearTimeout(timer) let res = undefined //返回值 //第一次是否不需要延迟 if(immediate && !isInvoke){ res = fn.apply(this,args) resolve(res) isInvoke = true return } //延迟执行对应的回调函数 timer = setTimeout(()=>{ //绑定this res = fn.apply(this,args) resolve(res) //执行完函数后timer置为null timer = null isInvoke = false },delay) }catch (err){ reject(err) } }) } //取消函数 _debounce.cancel = function (){ if(timer) clearTimeout(timer) timer = null isInvoke = false } //返回函数(闭包) return _debounce } 封装独立文件 // 原则: 一个函数进行做一件事情, 一个变量也用于记录一种状态 function hydebounce(fn, delay, immediate = false, resultCallback) { // 1.用于记录上一次事件触发的timer let timer = null let isInvoke = false // 2.触发事件时执行的函数 const _debounce = function(...args) { return new Promise((resolve, reject) => { try { // 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件 if (timer) clearTimeout(timer) // 第一次操作是不需要延迟 let res = undefined if (immediate && !isInvoke) { res = fn.apply(this, args) if (resultCallback) resultCallback(res) resolve(res) isInvoke = true return } // 2.2.延迟去执行对应的fn函数(传入的回调函数) timer = setTimeout(() => { res = fn.apply(this, args) if (resultCallback) resultCallback(res) resolve(res) timer = null // 执行过函数之后, 将timer重新置null isInvoke = false }, delay); } catch (error) { reject(error) } }) } // 3.给_debounce绑定一个取消的函数 _debounce.cancel = function() { if (timer) clearTimeout(timer) timer = null isInvoke = false } // 返回一个新的函数 return _debounce } 节流

我们可以通过一幅图来认识这个过程 在这里插入图片描述 节流的应用场景: ➢ 监听页面的滚动事件; ➢ 鼠标移动事件; ➢ 用户频繁点击按钮操作; ➢ 游戏中的一些设计

我们按照如下思路来实现:

 节流函数的基本实现:可以实现节流效果  优化一:节流最后一次也可以执行  优化二:优化添加取消功能  优化三:优化返回值问题

基本实现 function myThrottle(fn,interval){ let startTime = 0 return _throttle = function (){ let nowTime = new Date().getTime() let waitTime = interval - (nowTime - startTime) if(waitTime let startTime = 0 return _throttle = function (...args){ let nowTime = new Date().getTime() let waitTime = interval - (nowTime - startTime) if(waitTime let startTime = 0 return _throttle = function(...args) { let nowTime = new Date().getTime() // 控制是否立即执行 if (!leading && startTime === 0) { startTime = nowTime } let waitTime = interval - ( nowTime - startTime) if (waitTime


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3