feat: 复习节流与防抖

This commit is contained in:
LouisFonda 2024-04-08 07:13:46 +08:00
parent d87dee6e3d
commit defec92bf7
4 changed files with 236 additions and 0 deletions

96
html/节流.html Normal file
View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节流</title>
</head>
<body>
<div style="height: 100px;width: 100px;">
</div>
<button>点击我更换颜色</button>
<script>
function throttle(fun, delay){
var flag = true // 是否可以执行
return function(){
if(flag){
var args = arguments
var context = this
fun.apply(context, args)
flag = false
setTimeout(function(){
flag = true
}, delay)
}
}
}
function lastThrottle(fun, delay) {
var timer = 0
return function () {
if(timer) return
var args = arguments
var context = this
timer = setTimeout(function () {
fun.apply(context, args)
timer = 0
},delay)
}
}
function lastThrottleByTime(fun, delay) {
var pre = 0
return function () {
var cur = Date.now() // 获取当前的时间戳
if(cur - pre > delay) {
var args = arguments
var context = this
fun.apply(context, args)
pre = cur
}
}
}
function firstAndLastThrottle(fun, delay) {
var pre = 0
var timer = 0
var _delay = delay + 100 // 防抖用的时间间隔比节流大0.1秒因为人对0.1秒的延迟无感知
return function () {
var args = arguments
var context = this
var cur = Date.now() // 获取当前的时间戳
if(cur - pre > delay) {
fun.apply(context, args)
pre = cur
}
clearTimeout(timer)
timer = setTimeout(() => {
fun.apply(context, args)
}, _delay);
}
}
function setBgColor(el){
let r = Math.floor(Math.random()*256)
let g = Math.floor(Math.random()*256)
let b = Math.floor(Math.random()*256)
div.style.backgroundColor = `rgb(${r},${g},${b})`
}
let div = document.querySelector("div")
let button = document.querySelector("button")
setBgColor(div) // 初始化
// button.addEventListener("click",throttle(function(){
// setBgColor(div)
// },250))
// button.addEventListener("click",lastThrottle(function(){
// setBgColor(div)
// },2000))
// button.addEventListener("click",lastThrottleByTime(function(){
// setBgColor(div)
// },1000))
button.addEventListener("click",firstAndLastThrottle(function(){
setBgColor(div)
},250))
</script>
</body>
</html>

36
html/防抖.html Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>防抖</title>
</head>
<body>
<div>
<input type="text" id="input">
<p></p>
<input type="button" id="button">
</div>
<script>
function deBounce(fun, delay){
var timer = 0
return function(){
var args = arguments
var context = this
clearTimeout(timer)
timer = setTimeout(function(){
fun.apply(context, args)
},delay)
}
}
</script>
<script type="text/javascript">
let input = document.querySelector("input")
let p = document.querySelector("p")
input.addEventListener("input", deBounce(function(){
p.innerHTML = this.value
}
, 250))
</script>
</body>
</html>

87
js/节流.js Normal file
View File

@ -0,0 +1,87 @@
// 节流是值函数在连续触发的情况下在规定的时间内无论如何都会执行一次比如设置的延迟时间为250
// 那么如果连续点击1秒钟那么会执行4四次而且四次的时间间隔250
/**
* @description 节流函数(首节流第一次触发会立即执行)
* @param { Function } - 要添加节流功能的函数
* @param { number } - 要延迟的毫秒数
*/
export function firstThrottle(fun, delay) {
var flag = true // 是否可以执行
return function(){
if(!flag) return // 不能执行就直接返回
// 获取参数和上下文
var args = arguments
var context = this
fun.apply(context, args)
// 执行完成之后把flag设置成false表示不能执行并设置定时器delay毫秒之后设置true
flag = false
setTimeout(function(){
flag = true
}, delay);
}
}
/**
* @description 节流函数(尾节流无论延迟设置多久总会执行最后一次)
* @param { Function } - 要添加节流功能的函数
* @param { number } - 要延迟的毫秒数
*/
export function lastThrottle(fun, delay) {
var timer = 0
return function () {
if(timer) return
var args = arguments
var context = this
timer = setTimeout(function () {
fun.apply(context, args)
timer = 0
},delay)
}
}
/**
* @description 节流函数(首节流通过时间戳实现)
* @param { Function } - 要添加节流功能的函数
* @param { number } - 要延迟的毫秒数
*/
export function lastThrottleByTime(fun, delay) {
var pre = 0
return function () {
var cur = Date.now() // 获取当前的时间戳
if(cur - pre > delay) {
var args = arguments
var context = this
fun.apply(context, args)
pre = cur
}
}
}
// 思考首节流适用delay大且对最终状态无要求的功能缺点是不会执行最终状态。
// 尾节流适用delay不大且对最终状态有要求的功能缺点是当delay大时用户会认为自己的第一次点击好像无效
// 又没有什么办法可以是首节流,又保留最终状态?之前我们讲过防抖,防抖在高频率出发下,只会触发最后一次,这不就是我们要的尾状态吗!
/**
* @description 节流函数(首尾节流通过时间戳实现)
* @param { Function } - 要添加节流功L的函数
* @param { number } - 要延迟的毫秒数
*/
export function firstAndLastThrottle(fun, delay) {
var pre = 0
var timer = 0
var _delay = delay + 100 // 防抖用的时间间隔比节流大0.1秒因为人对0.1秒的延迟无感知
return function () {
var args = arguments
var context = this
var cur = Date.now() // 获取当前的时间戳
if(cur - pre > delay) {
fun.apply(context, args)
pre = cur
}
clearTimeout(timer)
timer = setTimeout(() => {
fun.apply(context, args)
}, _delay);
}
}

17
js/防抖.js Normal file
View File

@ -0,0 +1,17 @@
// 通过防抖,可以避免在用户快速连续地进行操作时(例如连续快速点击按钮),服务器或浏览器因为接收到过多无意义的重复请求而造成的性能瓶颈,从而提高页面性能和用户体验
/**
* @description 一个防抖函数
* @param { Function } - 需要添加防抖功能的函数
* @delay { number } - 防抖延迟的时间
*/
export default function deBounce(fun, delay) {
var timer = 0
return function() {
var args = arguments
var context = this
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
fun.apply(context, args)
})
}
}