1.函数的节流
一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。
应用场景:如用户不断滑动滚轮
实现原理:
A:用函数的闭包来锁住上一执行的时间,在用这一次执行的时间相比,大于设定的间隔时间则执行
B:也可以直接把lasTime放到全局去,不用闭包但这样就不好在事件监听的时候传递参数delay只能写死
这里我节流用闭包写,防抖就不用闭包了
用闭包就有一个问题,this的指向会非常复杂:匿名函数的执行环境具有全局性,this通常是指向window的,闭包内部this应该指向window,但这里是事件监听,this又重新指向监听的元素(document),而fn也是匿名函数内部this指向window,这里用apply修正this指向,使其重新指向document
<script type="text/javascript">
function throttle(fn, delay) {
console.log(this)//window
// 记录上一次函数触发的时间
var lastTime = 0;
return function() {
// 记录当前函数触发的时间
var nowTime = Date.now();
if(nowTime - lastTime > delay) {
/*
fn();
console.log(this)//document
*/
fn.apply(this)// 修正this指向问题
console.log(this)//document
// 同步时间
lastTime = nowTime;
}
}
}
document.onscroll = throttle(function() {
/*console.log(this)//window*/
console.log(this)//document
console.log('scroll事件被触发了' + Date.now())
}, 1000)
</script>
2.函数防抖
频繁触发的某一函数,只让最后一次执行
应用场景:用户多次点击提交表单
不用闭包后结构会很简单
<script type="text/javascript">
var timer = null;// 记录上一次的延时器
function debounce() {
console.log(timer)
clearTimeout(timer)
timer = setTimeout(function() {
console.log("aaa")
}, 1000)
}
document.getElementById('btn').onclick = debounce
</script>