JavaScript-防抖节流
# 防抖节流
# 防抖(debounce)
# 概念
笔记
触发后延迟执行代码,只执行最后一次(你一直触发,等你不触发了,过段时间再执行)
触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
# 使用场景
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
# 案例
利用防抖实现性能优化
// 需求:鼠标在盒子上移动,鼠标停止500ms之后,里面的数字就会变化+1
const box = document.querySelector('.box')
let i = 1
function mouseMove(){
box.innerHTML = i++
// 如果里面存在大量消耗性能的代码,比如DOM操作,比如数据处理,可能造成卡顿
}
// 添加事件
// box.addEventListener('mousemove',mouseMove)
// 利用lodash库实现防抖
// 语法:_.debounce(fun,时间)
box.addEventListener('mouseMove',_.debounce(mouseMove,500))
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 手写防抖函数
# 核心思路
利用定时器(setTimeout
)来实现
- 声明一个定时器变量
- 当鼠标每次滑动都先判断是否有定时器,如果有定时器先清楚以前的定时器
- 如果没有定时器则开启定时器,记得存到变量里面
- 在定时器里面调用要执行的函数
function debounce(fn,t){
let timer
// return 返回一个匿名函数(直接写函数只执行一遍)
return function(){
// 2.3.4
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
fn() // 加小括号调用fn函数
},t)
}
}
// debounce函数 鼠标还没动就执行了 每次鼠标滑动 需返回一个匿名函数
// 还没调用拿到return的值
box.addEventListener('mousemove',debounce(mouseMove,500))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 节流(throttle)
# 概念
笔记
触发后执行,间隔时间内再次触发不执行(你一直触发你的,但是我不管,我隔段时间就执行一遍)
连续触发事件但是在 n 秒中只执行一次函数
# 使用场景
高频事件:鼠标移动 mousemove
、页面尺寸缩放 resize
、滚动条滚动scroll
等等
# 案例
// 利用节流实现性能优化
// 需求: 鼠标在盒子上移动,里面的数字就会变化 + 1
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
box.innerHTML = i++
}
// 如果里面存在大量消耗性能的代码,比如dom操作,比如数据处理,可能造成卡顿
// box.addEventListener( 'mousemove',mouseMove)
// 利用Lodash库实现节流 - 500毫秒之后采取+1
// 语法:_.throttle(fun,时间)
box.addEventListener('mouseMove',_.throttle(mouseMove,500))
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 手写节流函数
利用节流来处理-鼠标滑过盒子显示文字 (手写节流函数 要求: 鼠标在盒子上移动,不管移动多少次,每隔
500ms
才 + 1
# 核心思路
节流的核心就是利用定时器(setTimeout
)来实现
声明一个定时器变量
当鼠标每次滑动都先判断是否有定时器了
如果有定时器则不开启新定时器如果没有定时器则开启定时器,记得存到变量里面
定时器里面调用执行的函数
定时器里面要把定时器清空
function throttle(fn,t){
let timer = null
return function(){
if(!timer){
timer = setTimeout(function(){
fn()
// 清空定时器(在定时器里面无法清除定时器clearTimeout,因为定时器还在运作)
// null把残留的数字直接覆盖掉
timer = null
},t)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 节流案例
页面打开,可以记录上一次的视频播放位置
# 思路
- 在
ontimeupdate
事件触发的时候,每隔1秒钟,就记录当前时间到本地存储 - 下次打开页面,
onloadeddata
事件触发,就可以从本地存储取出时间,让视频从取出的时间播放,如果没有就默认为0s - 获得当前时间
video.currentTime
# 两个事件
ontimeupdate
事件在视频/音频 (audio/video)当前的播放位置发送改变时触发onloadeddata
事件在当前的数据加载完成且还没有足够的数据播放视频/音频(audio/video)的下一帧时触发
const video = document.querySelector('video')
video.ontimeupdate = _.throttle(()=>{
// 把当前的时间存储到本地存储
localStorage.setItem('currentTime',video.currentTime)
},1000)
// 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给
video.currentTimevideo.onloadeddata = () => {
// console.log(111)
video.currentTime = localStorage.getItem( 'currentTime')||0
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
上次更新: 2024/08/14, 04:14:33