场景介绍:
在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。
定义
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
自我定义:不管多么听不懂,时间到就下课,简单明了。
场景:滚动页面加载数据,每隔一段时间发送一次请求,这样比较合理,如果按照用户滚动停止才请求中间一段时间内都看不到数据。
var throttle = function(func, delay) {
var timer = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = delay - (curTime - startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if (remaining <= 0) {
func.apply(context, args);
startTime = Date.now();
} else {
timer = setTimeout(func, remaining);
}
}
}
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
自我定义:无限穿越救人
场景:最简单的应用场景是提交按钮误触,点击多次提交。
function debounce(fn, wait) {
var timeout = null;
return function() {
if(timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
应用
购物车功能实现:
用户短时间内频繁点击添加购物车:使用节流,避免触发多次请求:点击购物车,监听点击事件,隔300ms才执行一次函数
用户长时间内持续点击添加购物车:使用防抖,当前按钮增减值,商品分类加入购物车数量改变,购物车数量和总价改变,不发送请求,等用户点击结束才发送请求。
伪代码
document.querySelector('.btn').addEventListener('click', throttle(actionCard, 300))
document.querySelector('.btn').addEventListener('click', debounce(addCard, 1000))
let actionCard = () => {
// 计算当前的数值
// 当前按钮增减值
// 商品分类加入购物车数量改变
// 购物车数量和总价改变
}
let addCard = () => {
// 发送数值给后台
axios.post('xxx', data).then(res =>{
// ..coding
})
}
举个例子
<button class="btn">0</button>
let actionCard = function(){
btn.innerHTML = 1 + parseInt(btn.innerHTML)
}
let addCard = function(){
console.log(btn.innerHTML)
}
let btn = document.querySelector('.btn')
btn.addEventListener('click', throttle(actionCard, 300))
btn.addEventListener('click', debounce(addCard, 1000))
// 按钮不断加,最后停下来,浏览器上打印出最后的值