防抖
很多项目有这样一个需求:监听输入框输入的内容
<input type = "text" id = "input" />
<script>
window.onload = function(){
var input = document.getElementById("input");
input.addEventListener('input', function(e) {
console.log(e.target.value);
});n
}
</script>
效果:
很明显可以看到在极短时间内重复输入都会触发监听事件,这虽然每次都可以获得最新的输入内容,但这性能上就显得比较差一些,所以我们可以采用【防抖】来做性能优化:
<input type = "text" id = "input" />
<script type="text/javascript">
window.onload = function() {
var input = document.getElementById("input")
let timer = null; // 定义一个全局的定时器对象变量
input.addEventListener('input', function (e) { // 监听其input事件
clearTimeout(timer); // 清除上一个定时器
timer = setTimeout(function () {
console.log(e.target.value); // 代表 AJAX 请求
}, 500);
});
}
</script>
防抖的思路是:短时间 t 内的多次操作,会舍弃掉前面的上一次的操作,等到时间 t 一过才将此次操作弹出
所以防抖的关键步骤就是:
- 规定时间内的每次操作,都会各自清除之前的工作记录(即定时器)
clearTimeout(timer) - 规定时间一过,没有被干扰到的那个操作顺利完成工作(定时器计时完成,做出一些处理)
timer = setTimeout(fn,delay)
效果:
节流
假如有这么一个需求:右边滚动条在滑动时,如果超过一定的范围,则左边的分类栏要同步更新显示当前所处的范围对应的类别:
那我们很容易想到的思路就是
- 监听滑动事件,实时获取到滚动条当前所处位置到顶部的距离
- 根据这个距离判断属于哪个范围,然后对数据做出修改
所以关键步骤在于:监听滑动事件,实时获取到滚动条当前所处位置到顶部的距离
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = showTop
效果:
可以看到,我们在极短时间内超多次获取滚动条位置,所以这个时候我们需要做一下节流优化:
// 节流函数
function throttle(fn,delay){
let flag = true
return function() {
if(!flag){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
flag = false
setTimeout(() => {
fn()
flag = true;
}, delay)
}
}
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = throttle(showTop,1000)
节流的思路是:短时间 t 内的多次操作,我们只取这个时间 t 内的最后一次操作
所以节流的关键步骤就是:
- 当监听到一次操作,就 启动一个定时器 并 “关上大门”
flag = false - 在定时器未完成计时内 阻止 往后的操作
if(!flag) - 在定时器完成计时后 “打开大门”
flag = true - 回到了第 1 步
效果:
总结
防抖的思路是:短时间 t 内的多次操作,会舍弃掉前面的上一次的操作,等到时间 t 一过才将此次操作弹出
节流的思路是:短时间 t 内的多次操作,我们只取这个时间 t 内的最后一次操作