js节流
原理:在N秒内就触发一次,若在N秒内重复被触发,只有第一次生效。
场景:滚动页面,监听页面滚动到底部的时候触发,现在基本都是使用数据分页
拖拽场景,固定时间内只执行一次,防止高频率的位置变动。
<!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 {
height: 2000px;
width: 100%;
background-color: aqua;
}
</style>
</head>
<body>
</body>
<script>
let count = 1;//这个是为了统计触发了几次事件
function scrollFn() {
console.log('监听到了事件变化', count++)
}
/*
借助setTimeout定时器,控制后续的事件是否执行
获取每次事件执行的时间与上一次执行的时间差
判断时间差是否已经超出自己设定的时间间隔
如果时间已经超过则会立即执行函数
如果没有超过则会取消后续的定时器任务
最后一次事件的触发,会执行完成
*/
function throttle(fn, time) {
//定义一个上次执行的时间第一次为0
let pro = 0;
//定义一个定时器函数
let timeout = null;
return function (...args) {
//计算时间差
const now = Date.now();
//如果时间差朝超过我们规定的时间
if (now - pro > time) {
pro = now;
fn.apply(this, args)
} else {
//如果时间没有超出我们规定的时间间隔,我们就判断timeout是否存在,如果存在就清除
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
}
//这是为了用户最后一次触发可能正好在时间间隔内,就是用户停止滚动了触发最后一次事件
timeout = setTimeout(() => {
//因为触发了一次所以就把当前时间设置为触发时间作为下一次的时间做对比
per = now;
fn.apply(this.args)
},time)
}
}
const newFn=throttle(scrollFn,500)
document.onscroll = newFn;
</script>
</html>