这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
是什么?
节流的原理是,我们给定一个时间(n),在这个时间(n)内,无论我们怎么触发,他都只会执行一次,等这个时间过去了,我们才会进行第二次执行,然后再等n秒,再进行第三次执行。。。一直这样下去
为什么?
在日常业务开发中,会有很多频繁触发的事件,如果我们不对他们做一些处理,会有很大的性能问题。处理不当或者放任不管就容易引起浏览器卡死。
我们应该都有做过这样的需求,监听页面的滚动事件,滚动到一定的地方,顶部的tab栏的高亮会跟着定位改变,如果使用防抖来处理频繁触发事件的话,如果用户一直滚动,不停,那么tab栏的高亮永远不会做出反应,这个时候我们就可以使用节流来处理了,一定时间内就算用户一直在触发事件,我们也给他做出响应,高亮对应tab
怎么用
简单实现 我创建了一个box,然后在这个box上进行了mousemove事件,每次触发事件都对value值进行增加
<!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>
<style>
body {
margin-top: 100px;
display: flex;
justify-content: center;
background: #BFA2DB;
}
#div1 {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
color: #7F7C82;
background-color: #F3F1F5;
}
</style>
</head>
<body>
<div id="div1"></div>
<script>
var value = 1;
var div1 = document.getElementById('div1');
function count() {
div1.innerHTML = value++;
};
div1.onmousemove = count;
</script>
</body>
</html>
可以看到,一直在移动。根据上面是什么的描述,我们可以根据时间戳去实现这个节流的简单函数
div1.onmousemove = throttle(count,3000);
function throttle(fn, wait) {
let prev = 0
return (...args) => {
let now = +new Date()
if (now - prev > wait) {
fn.apply(this, args)
prev = now
}
}
}
现在,我给他设置了3s内只执行一次,可以看到,我在上面一直触发事件,但他每三秒才会执行一次。
我们也可以使用定时器去实现
div1.onmousemove = throttle(count, 2000);
function throttle(fn, wait) {
let timer = 0
return (...args) => {
if (!timer) {
timer = setTimeout(function () {
timer = null;
fn.apply(this, args)
}, wait)
}
}
}
当鼠标移入的时候,事件不会立刻执行,2s后执行了一次,6.2s 的时候停止触发,但是依然会在第 8s 的时候执行一次事件。
之后,还可以对这个函数进行优化,进入就执行,移除事件之后就不再执行。