防抖 | 节流 | |
---|---|---|
概念 | 连续的事件,只最后一次触发回调 (如:停止滚动滑动条时,触发一次回调) | 连续的事件,间隔一段时间执行一次回调 (如:滚动滚动条时,每隔一段事件触发一次回调) |
应用场景 | 避免用户快速点击按钮,持续发送请求 搜索框持续输入 手机号、邮箱验证 鼠标的mousemove、mouseover | 滚动加载,加载更多 搜索框联想功能 |
事件触发n秒后才能再次发起请求
例:用防抖模拟解决输入框多次发起请求问题
<input type="text"/>
//js
var int = document.querySelector("input");
int.oninput = function(){
console.log(this.value) //模拟业务逻辑
}
var int = document.querySelector("input");
var time = null; //初始化定时器
int.oninput = function(){
if(time != null){ //判断是否已存在定时器
clearTimeout(time) //清空定时器
}
time = setTimeout(() => {
console.log(this.value); //模拟业务逻辑
}, 500);
}
效果如下:
1、封装业务逻辑
//业务逻辑
function task(){
console.log(this.value); //模拟业务逻辑
}
2、封装防抖函数
function debounce(){
return function(){}
}
function debounce(fn,delay){
let time = null
return function(){
//此处是防抖逻辑
}
}
3、组装业务逻辑函数和防抖函数(完整代码)
var int = document.querySelector("input");
int.oninput = debounce(task,500)
//业务逻辑
function task(){
console.log(this.value);
}
//防抖函数
function debounce(fn, delay){
var time = null;
return function(){
if(time != null){
clearTimeout(time)
}
time = setTimeout(() => {
fn.call(this) // 注:此处需改变this指针,否则业务逻辑中的this指向window
}, delay);
}
}
控制执行次数,n秒内多次触发事件只有1次生效
例:用节流模拟解决滑动浏览器多次请求的问题
<style>
body{
height: 10000px;
}
style>
//js
window.onscroll = function(){
console.log('触发')
}
2、设置标记变量,限制值为true时,进入计时器计时并执行业务逻辑
3、设置setTimeOut,定时器在规定时间后才能再次触发
var flag = true;
var time = null;
window.onscroll = function(){
if(flag){ //标记变量为true时开始计时
time = setTimeout(() => {
console.log('触发')
flag = true;
}, 500);
}
flag = false; //n秒内flag值为false,不触发计时器
}
效果如下:
1、封装业务逻辑
function task(){
console.log('触发');
}
2、封装防抖函数
function throttle(){
return function(){
}
}
function throttle(fn,delay){
var flag = true;
var time = null;
return function(){
}
}
3、组装业务逻辑函数和防抖函数(完整代码)
window.onscroll = throttle(task, 500)
//业务逻辑
function task(){
console.log('触发');
}
//节流函数
function throttle(fn,delay){
var flag = true;
var time = null;
return function(){
if(flag){
time = setTimeout(() => {
fn.call(this)// 注:此处需改变this指针,否则业务逻辑中的this指向window
flag = true;
}, delay)
}
flag = false;
}
}