节流
只允许一个函数在 X 毫秒内执行一次
详解:
如果需要统计用户滚动屏幕的行为来做出相应的网页反应,就需要进行节流,因为如果用户不断地滚动,就会不断产生请求,响应也会不断增加,容易导致网络阻塞。
解决办法是:在触发事件的时候马上执行任务,并设定时间间隔限制,在这段时间内,不管用户如何进行滚动都忽视操作,时间到了以后,如果检测到用户有滚动行为,再次执行任务并设置时间间隔。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<script type="text/javascript">
// 窗口大小变化的监听函数
function coloring() {
let r = Math.floor(Math.random() * 255)
let g = Math.floor(Math.random() * 255)
let b = Math.floor(Math.random() * 255)
document.body.style.background = `rgb(${r}, ${g}, ${b})`
}
// 节流函数
function throttle(fun, delay){
let timer
// 高阶函数
return function() {
let context = this
let args = arguments
// 如果timer为true,也就是被赋值了,那么直接返回,不执行任务
if(timer) {
return
}
// 如果timer为false,也就是没被赋值或者任务已经完成
timer = setTimeout(function() {
// 延迟之后执行函数,执行完成之后就是将时间设置为null,此时距离上一次调用已经过去了2s
fun.apply(context, args)
// 执行完之后要清空timer
timer = null
}, delay)
}
}
// window窗口设置监听器
window.addEventListener('resize', throttle(coloring,2000))
</script>
</body>
</html>
防抖
多个顺序地调用合并成一次,也就是在一定时间内,规定事件被触发的次数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<button id="input">按钮</button>
<script type="text/javascript">
const button = document.getElementById('input')
// 点击处理事件
function payMoney() {
console.log('点击')
// console.log(this)
}
// 防抖函数
function debounce(fun,delay) {
// 相当于多个函数公用一个外部变量
let timer
// 高阶函数是一个接收函数作为参数或将函数作为输出返回的函数
return function(){
let context = this
let args = arguments
// 清除延时
clearTimeout(timer)
// 延时执行防抖函数
timer = setTimeout(function() {
fun.apply(context, args)
console.log("调用时:", context)
console.log("调用时:", args)
}, delay)
}
}
// 延时1秒
button.addEventListener('click', debounce(payMoney, 2000))
</script>
</body>
</html>
区别
- 与防抖相比,节流函数最主要的不同在于它保证在 X 毫秒内至少执行一次我们希望触发的事件 handler。
- 与防抖相比,节流函数多了一个 mustRun 属性,代表 mustRun 毫秒内,必然会触发一次 handler ,同样是利用定时器,