防抖、节流
防抖(debounce)
JS中的防抖是指触发一个事件后,在一段时间内函数只执行一次,如果在这段时间内事件再次被触发,则重新计算这段时间。
例如你进公司,公司大门口安装了一个感应门,它感应人进去十秒后关门,当第一个人进去之后,开始十秒钟倒计时,在这十秒钟第二个人进去了,在第二个人进去之后,将之前的倒计时清空,计时器重新调整到十秒,倒计时结束后关门。
为什么需要防抖呢?
如果没有防抖,感应门每进去一个人立即关门,在人多的时候,会频繁开关门,损耗较大。
一个小实现
页面的滚动条,滚动的时候在控制台输出scrollTop
<!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>Document</title>
</head>
<body>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<h1>111111111</h1>
<script>
window.onscroll = function() {
var top = document.documentElement.scrollTop || document.body.scrollTop;
console.log(top);
}
</script>
</body>
</html>
在页面发生滚动的时候,控制台疯狂输出当前的scrollTop,这样对性能的消耗也会变得比较大,防抖处理后的页面。
window.onscroll = play();
function play() {
var timer = null;
return function() {
//清除定时器
clearTimeout(timer);
//创建定时器
timer = setTimeout(function() {
var top = document.documentElement.scrollTop || document.body.scrollTop;
console.log(top);
}, 100)
}
}
这样处理之后,页面会在滚动条滚动之后的100毫秒之后才会输出页面的scrollTop值,而不是不停地输出。
防抖的应用场景
防抖可以在输入手机号、用户名等进行判定的时候使用,也可以在浏览器的窗口发生变化,滚动条发生变化的时候使用。
节流
节流是指一个事件不论被触发多少次,在一段时间内只执行一次。
在一个事件被触发时开启计时器,在计时器倒计时的这一段时间内,无论事件被触发了多少次,只会在计时器结束后执行一次计时器里面的内容,执行内容后,事件被触发才能再次开启计时器。
继续使用浏览器的滚动事件举例,在不停的滚动浏览器的滚动条时,在最开始滚动的时候开启定时器,等待定时器结束后打印当前的scrollTop,然后重新开启定时器。
window.onscroll=throttle(500);
function throttle(delay){
var start=0;//初始化第一次执行的时间点
return function(){
//每次滚动时调用内部函数
var now = Date.now();
//用当前时间 - 上次执行的时间
var sub = now - start;
//计算看是否超过了500毫秒
if(sub>delay){
//如果超过了500毫秒,去执行一次代码
var top = document.documentElement.scrollTop || document.body.scrollTop;
console.log(top);
//执行完业务代码之后,将当前时间作为下一次执行的开始时间
start=now;
}
}
}
节流不清空定时器,当计时器结束执行完内容之后事件触发再次开启定时器。
应用场景
搜索框:在开始输入搜索内容之后,每一段时间自动搜索一次。