1 .认识节流throttle函数
节流的过程
- 当事件触发时,会执行这个事件的响应函数;
- 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
- 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的;
节流的应用场景:- 监听页面的滚动事件;
- 鼠标移动事件;
- 用户频繁点击按钮操作;
- 游戏中的一些设计;
游戏理解: 节流就是英雄CD
生活理解: 坐电梯时每一层的到达时间
2. Underscore实现节流
<!-- //第三方库使用防抖节流 -->
<input type="text">
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script>
<script>
const inputEl = document.querySelector('input')
let count = 0
const inputChange = function (event) {
count++
console.log(`发送了我们的第${count}次网络请求`, this,event);
}
// // 防抖只执行一次
// inputEl.οninput=_.debounce(inputChange,2000)
// 节流固定的时间进行触发
inputEl.oninput = _.throttle(inputChange, 2000)
3 手写节流
- 图解节流的实现
3. 1节流函数的基本实现
<!-- //第三方库使用防抖节流 -->
<input type="text">
<button id="cancel">取消</button>
<!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script> -->
<script>
const inputEl = document.querySelector('input')
let count = 0
const inputChange = function (event) {
count++
console.log(`发送了我们的第${count}次网络请求`, this, event);
}
// 节流固定的时间进行触发
inputEl.oninput = throttle(inputChange, 2000)
// 封装节流 :关键在于: 节流阀 以及时间间隔
function throttle(callback, times) {
let lastTime=0 //初始值
// 在接受这两个值时需要返回一个函数
const _throttle = function (...args) {
// 获取当前时间的秒数
const nowTime=new Date().getTime()
// 2-(无穷大-0)=-数 执行
// 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
const remainTime= times-(nowTime- lastTime)
if (remainTime<=0) {
callback.call(this,args)
// 重新赋值后 times还是2s不调用callback节流阀函数
lastTime=nowTime //第二次执行的初始时间(保留上次触发的时间)
}
}
return _throttle
}
优化
<input type="text">
<button id="cancel">取消</button>
<!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script> -->
<script>
const inputEl = document.querySelector('input')
let count = 0
const inputChange = function (event) {
count++
console.log(`发送了我们的第${count}次网络请求`, this, event);
}
// 节流固定的时间进行触发
inputEl.oninput = throttle(inputChange, 2000)
// 封装节流 :关键在于: 节流阀 以及时间间隔
//1 如果不触发函数则节流阀关闭状态
// 当你触发这个函数时先把节流阀关闭 然后在默认的时间间隔中打开
function throttle(callback, delaytime) {
let state=true //节流阀打开
return function(){
if (!state) { //当节流阀关闭,则直接退出该函数
return; //callback不执行
}else{
//如果节流阀打开先把节流阀关闭
//然后设置时间间隔后在自动打开
state = false
setTimeout(() => {
callback && callback()
state = true
}, delaytime)
}
}
}
</script>
后期优化
优化一:节流最后一次也可以执行
优化二:优化添加取消功能
优化三:优化返回值问题