防抖 --debounce
是指单位时间内,频繁触发事件,只执行最后一次
例如:一段3s就可以执行完的事件,在3s还没到,我又因为其他事情耽误了我这一段进程,这次的执行就作废了,按照重新触发的那次重新计算完成进度 只要被打断就要重新来
处理方式:
html
<script>
const box = document.querySelector('.box')
let i = 0 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// 防抖函数
function debounce(fn, t) {
let timeId
return function () {
// 如果有定时器就清除
if (timeId) clearTimeout(timeId)
// 开启定时器 200
timeId = setTimeout(function () {
fn()
}, t)
}
}
// box.addEventListener('mousemove', mouseMove)
box.addEventListener('mousemove', debounce(mouseMove, 200))
</script>
防抖的核心就是 定时器;
lodash防抖和节流
html
<div class="box"></div>
<!-- <script src="./lodash.min.js"></script> -->
<script src="js/lodash.min.js"></script>
<script>
const box = document.querySelector('.box')
let i = 0 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// box.addEventListener('mousemove', mouseMove)
// lodash 节流写法
box.addEventListener('mousemove', _.throttle(mouseMove, 500))
// lodash 防抖的写法
// box.addEventListener('mousemove', _.debounce(mouseMove, 1000))
</script>
节流 -- throttle
如果一个进程要3s, 那么在我执行这3s期间,不管触发多少次,我都会等这次执行完再去执行下一次触发。
问题:
手写核心思路:
注意在定时器内清除定时器要用 timeId=null
html
//第一种写法
<div class="box"></div>
<script>
const box = document.querySelector('.box')
let i = 0 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// 节流函数
function throttle(fn, t) {
let timeId = null
return function () {
// 如果没有定时器就开一个
if (!timeId)
timeId = setTimeout(function () {
fn()
//执行完之后再清空
timeId = null
}, t)
}
}
// box.addEventListener('mousemove', mouseMove)
box.addEventListener('mousemove', throttle(mouseMove, 3000))
</script>
html
//第二种写法
<div class="box"></div>
<script>
const box = document.querySelector('.box')
let i = 1 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// console.log(mouseMove)
// 节流函数 throttle
function throttle(fn, t) {
// 起始时间
let startTime = 0
return function () {
// 得到当前的时间
let now = Date.now()
// 判断如果大于等于 500 采取调用函数
if (now - startTime >= t) {
// 调用函数
fn()
// 起始的时间 = 现在的时间 写在调用函数的下面
startTime = now
}
}
}
box.addEventListener('mousemove', throttle(mouseMove, 500))
节流案例--视频记录上次定位
html
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
// 1. 获取元素 要对视频进行操作
const video = document.querySelector('video')
video.ontimeupdate = _.throttle(() => {
// console.log(video.currentTime) 获得当前的视频时间
// 把当前的时间存储到本地存储
localStorage.setItem('currentTime', video.currentTime)
}, 1000)
// 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给 video.currentTime
video.onloadeddata = () => {
// console.log(111)
video.currentTime = localStorage.getItem('currentTime') || 0
}
</script>