说明
1. 防抖与节流
1.1 防抖
-
防抖
: 触发事件后,在n秒内函数只执行一次 -
记忆: 你手比较抖,不小心按了按钮2下…你只希望它只执行一次.且按第二次结束时间算…这就用到了防抖技术
1.2 节流
节流
: 连续发生的事件,在n秒内只执行一次函数
1.3 防抖与节流的区别
- 在一段时间内,不管触发多少次事件,事件处理函数都只处理一次称之为节流
- 防抖,是在最后一次事件发生时开始计算,到固定时间触发
1.4 准备工作
- 准备一个给定宽、高的盒子,初始化显示为0.(innerHTML = 0)
- 当鼠标移入盒子的时候,触发鼠标移动事件(box.onmousemove)
- 鼠标移动事件的处理函数: 当鼠标在盒子中移动的时候,会将一个全局变量(count)加1并写入盒子中
<!DOCTYPE html>
<html lang="en">
<head>
<title>防抖与节流</title>
<style>
.box {
width: 150px;
height: 150px;
margin: 50px auto;
line-height: 150px;
text-align: center;
border: 1px solid black;
font-size: 50px;
}
</style>
</head>
<body>
<div id="box" class="box">0</div>
<script>
var box = document.getElementById('box')
var count = 1
box.onmousemove = function() {
box.innerHTML = count++
}
</script>
</body>
</html>
1.5 防抖的实现(先等待在执行)
- 思路:
- 在事件处理器中放一个延迟执行函数(setTimeout)
- 每触发一次,清除上一次的事件处理函数(clearTimout)
var box = document.getElementById('box')
var count = 1
var timer = null;
function debounce() {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
box.innerHTML = count++;
}, 1 * 1000);
}
box.onmousemove = debounce
1.5.1 防抖的改进
- 上面的等待时间和处理函数是静态的,封装成动态的
var debounce = (handUp, fn) {
var timer = null;
return function (){
if(timer) clearTimeout(timer);
timer = setTimeOut(function(){
fn.call(this, arguments)
}, handUp)
}
}
box.onmousemove = debounce(1000, function(){
box.innerHTML = count++;
})
1.6 防抖的实现(先执行在等待)
- 描述: 触发事件处理函数的时候,先执行一次函数,然后过n秒后再执行
- 思路:
- 由于核心是异步函数(setTimeout)的清除.
- 用一个flag函数记录当前定时器的状态,如果定时器为空则代表执行
function debounce(handUp, fn) {
// 进来的时候设置为null
var timer = null
return function() {
if (timer) clearTimeout(timer)
var flag = !timer
timer = setTimeout(() => {
timer = null
}, handUp)
if (flag) fn.apply(this, arguments)
}
}
1.7 节流的实现
- 描述: 在给定时间内,无论时间处理函数触发多少次都只执行一次
- 思路:
1.根据timer是否为空,如果为空则执行一次.
2.在给定时间后,将定时器的序号timer清空.让它可以重新执行
function throttle(handUp, cb){
var timer = null;
return function(){
if(!timer){
timer = setTimeout(()=>{
cb.apply(this);
timer = null;
}, handUp)
}
}
}
1.8 节流的实现(不使用定时器)
- 触发的第一次的时候,先记录第一次执行的时间(last)
- 触发然后随着函数不断触发,得到第一个时间间隔大于给定时间的环境.
- 触发给定的函数,然后将last设置为当前时间
function throttle(handUp, cb){
var last = 0;
return function(){
var now = Date.now();
if(now - last > handUp){
last = now;
cb.apply(this);
}
}
}