1.什么是防抖?
事件响应函数(doSomeThing)在一段时间(await)之后才执行,如果这段时间内再次调用函数,则重新计算时间。
应用场景:
1,scroll时间滚动触发
2,搜索框输入查询
3,表单验证
4,按钮提交事件
5,浏览器窗口缩放,resize事件
一般情况包括频繁操作,回调,发生ajax造成页面性能消耗,卡顿现象时,会用到防抖操作
手写防抖需要解决的问题:
1,this的指向问题
2,参数的传递event
3,防抖函数的第三个参数,控制只要触发立即执行
4,取消防抖操作
手写函数:
function debounce(func, await, immediate) {
let timeout, result;
let debounced = function () {
let that = this;
let args = arguments;
clearTimeout(timeout);
if (immediate) {
let callNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, await);
//给func添加一个返回结果
//立即执行
if (callNow) result = func.apply(that, args);
} else {
//不会立即执行
timeout = setTimeout(function () {
func.apply(that, args);
}, await);
}
return result;
};
//添加一个取消防抖操作的函数
debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}
let count = 0;
let box = document.querySelector(".box");
let btn = document.querySelector("#btn");
let doSome = debounce(doSomeThing, 3000);
function doSomeThing(e) {
box.innerHTML = count++;
console.log(count);
}
box.onmousemove = doSome;
btn.onclick = function () {
doSome.cancel();
};
2,什么是节流
原理:如果持续触发事件,每隔一段时间,只执行一次事件
应用场景:
1.DOM元素的拖拽功能实现
2.射击游戏
3.计算鼠标移动距离
4.监听scroll滚动事件
// 1.使用时间戳实现节流函数
// 第一次调用,最后一次不调用触发函数,leading:true,training:false
function throttle(func, await) {
let that,arguments;
let old = 0;
return function () {
that=this
args=arguments
let now = Date.now();
if (now - old > await) {
//立即执行
func.apply(that,args);
old=now
}
};
}
//2.使用定时器完成
//第一次不会触发,最后一次会触发,leading:false,training:true
function throttle(func, await) {
let that, args, timeout;
return function () {
that = this;
args = arguments;
if (!timeout) {
timeout = setTimeout(function () {
timeout = null;
func.apply(that, args);
}, await);
}
};
}
//3.两个方法结合一下实现第一次触发,最后一次也触发,leading:true,training:true
function throttle(func, await) {
let that, args, timeout;
let old = 0;
return function () {
that = this;
args = arguments;
let now = Date.now();
if (now - old > await && !timeout) {
func.apply(that, args);
old = now;
console.log(1222);
}
if (!timeout) {
timeout = setTimeout(function () {
timeout = null;
func.apply(that, args);
old = Date.now();
console.log(2333);
}, await);
}
};
}
//4.实现第三个参数
function throttle(func, await, options) {
let that, args, timeout;
let old = 0;
if (!options) options = {};
return function () {
that = this;
args = arguments;
let now = Date.now();
if (options.leading === false && !old) {
old = now;
}
//首次触发立即执行
if (now - old > await && !timeout) {
func.apply(that, args);
old = now;
console.log(1222);
}
if (!timeout && options.traing !== false) {
timeout = setTimeout(function () {
timeout = null;
func.apply(that, args);
old = Date.now();
console.log(2333);
}, await);
}
};
}