防抖就是当事件被触发一段时间后再执行回调,如果在这段时间内事件又被触发,则重新计时
防抖函数分为 非立即执行和立即执行
非立即执行版:触发事件后函数在 n 秒后执行,如果在 n 秒内又触发了则重新计时
function debounce(func, wait) {
var timer;
return function () {
if (timer) clearTimeout(timer);
var _this = this;
timer = setTimeout(function(){
func.apply(_this, arguments)
}, wait);
}
}
// let _this = this;让 debounce 函数最终返回的函数 this 指向不变以及依旧能接收到参数
立即执行版:触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果
function debounce(func,wait) {
var timer;
return function () {
var _this = this;
if (timer) clearTimeout(timer);
var callNow = !timeout;
timer = setTimeout(function(){
timer = null;
}, wait)
if (callNow) func.apply(_this, arguments)
}
}
二者结合:
/**
* wait 延迟执行毫秒数
* immediate true 表立即执行,false 表非立即执行
*/
function debounce(func,wait,immediate) {
var timer;
return function () {
var _this = this;
if (timer) clearTimeout(timer);
if (immediate) {
let callNow = !timer;
timer = setTimeout(function(){
timer = null;
}, wait)
if (callNow) func.apply(_this, args)
}
else {
timer = setTimeout(function(){
func.apply(_this, arguments)
}, wait);
}
}
}
节流就是指定时间间隔内,若事件被多次触发,只会执行一次。
节流有两种方式实现,时间戳版和定时器版
时间戳版:
function throttle(func, wait) {
var lastTime = 0;
return function() {
var nowTime = Date.now();
var context = this;
if (nowTime - lastTime > wait) {
func.apply(context, arguments);
lastTime = nowTime;
}
}
}
定时器版:
function throttle(func, wait) {
var timer;
return function() {
var _this = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function(){
timer = null;
func.apply(_this, args)
}, wait)
}
}
}
二者区别:时间戳版的函数触发是在时间段内开始时,而定时器版的函数触发是在时间段内结束时
二者结合:
/**
* wait 延迟执行毫秒数
* type 1 表时间戳版,2 表定时器版
*/
function throttle(func, wait ,type) {
if(type===1){
var lastTime = 0;
}else if(type===2){
var timer;
}
return function() {
var _this = this;
if(type===1){
var nowTime = Date.now();
if (nowTime - lastTime > wait) {
func.apply(_this, arguments);
lastTime = nowTime;
}
}else if(type===2){
if (!timer) {
timer = setTimeout(function(){
timer = null;
func.apply(_this, arguments)
}, wait)
}
}
}
}