防抖函数:
是在事件触发后,设置一个定时器,在指定的延迟时间内如果再次触发了该事件,就清除之前的定时器重新设置一个新的定时器。只有在延迟时间内没有再次触发事件时,才执行最后一次触发事件时的操作。
防抖函数的基本原理:
-
初始化一个定时器变量,用于存储定时器的标识符。
-
当事件触发时,清除之前的定时器。
-
创建一个新的定时器,在指定的延迟时间后执行指定的操作。
-
如果在延迟时间内再次触发了事件,则重复步骤2和步骤3,清除之前的定时器并创建一个新的定时器。
-
如果在延迟时间内没有再次触发事件,定时器触发并执行指定的操作。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>利用防抖实现性能优化</title> <style> .box { width: 500px; height: 500px; background-color: #ccc; color: #fff; text-align: center; font-size: 100px; } </style> </head> <body> <div class="box"></div> <script src="./js/lodash.min.js"></script> <script> // 利用防抖实现性能优化 //需求: 鼠标在盒子上移动,里面的数字就会变化 + 1 const box = document.querySelector('.box') let i = 0 box.addEventListener('mousemove', debounce(mouseMove, 500)) // 封装事件处理函数 function mouseMove() { i++ box.innerHTML = i } // 防抖:在单位时间(函数执行设置的时间)内,某个动作被多次触发,只执行最后一次 // 形参分别是事件处理函数和单位时间 function debounce(fn, t) { let timerId // 闭包:内层函数调用外层函数的变量 // 会返回一个函数 用来事件处理 给事件处理函数 return function () { // 清理定时器 clearTimeout(timerId) // 设置定时器 timerId = setTimeout(() => { // 执行事件处理函数 fn.call(box) }, t) } } </script> </body> </html>
通过这种方式,防抖函数可以确保只有在最后一次触发事件后的延迟时间内没有再次触发事件时,才执行相应的操作。这在一些需要避免频繁触发事件而只关注最后一次触发的情况下非常有用,例如输入框输入联想、滚动事件等。
节流函数:
一种用于限制函数执行频率的技术。它可以确保在一定时间间隔内,函数最多执行一次。与防抖函数不同,节流函数会按照固定的时间间隔执行函数,而不是在最后一次触发后等待一段时间执行。
节流函数的基本原理:
-
初始化一个定时器变量和上次执行的时间变量。
-
当事件触发时,获取当前时间。
-
检查当前时间与上次执行的时间间隔是否超过指定的时间间隔。
-
如果超过了时间间隔,立即执行函数,并更新上次执行的时间变量。
-
如果未超过时间间隔,清除之前的定时器。
-
设置一个新的定时器,在剩余的时间间隔后执行函数,并更新上次执行的时间变量。
通过这种方式,节流函数可以限制函数的执行频率,在一定的时间间隔内最多执行一次函数。无论事件触发多频繁,都可以保证函数按照指定的时间间隔被调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>利用防抖实现性能优化</title>
<style>
.box {
width: 500px;
height: 500px;
background-color: #ccc;
color: #fff;
text-align: center;
font-size: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script src="./js/lodash.min.js"></script>
<script>
// 利用防抖实现性能优化
//需求: 鼠标在盒子上移动,里面的数字就会变化 + 1
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
this.innerHTML = i++
}
// 添加事件
// box.addEventListener('mousemove', mouseMove)
// 防抖:单位时间内,多次触发事件,只执行最后一次
// 节流:单位时间内,多次触发事件,只会生效一次
// 节流方法
box.addEventListener('mousemove', throttle(mouseMove, 1000))
// 封装函数
function throttle(fn, t) {
let timerId
// 会返回一个事件处理函数
return function () {
// 判断是否开启过定时器,如果没有才能开始
if (!timerId) {
timerId = setTimeout(() => {
fn.call(this)
// 清除timerId
timerId = null
}, t)
}
}
}
</script>
</body>
</html>
节流函数 throttle
会确保 mousemove函数在每隔 1 秒的时间间隔内最多执行一次。即使多次调用 throttledFn
,函数的执行频率也受到限制。