//防抖函数
// 防抖的概念
// 短时间内大量触发同一事件,只会执行一次函数,实现原理为设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作,
// 防抖常用于搜索框/滚动条/按钮点击 的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费
/**
* func => 执行的函数体
* wait => 等待的时间
* immediate => 是否立即执行
*/
function debounce(func, wait, immediate) {
//timeout => 控制间隔保存计时器的变量
//result => 执行函数如果有返回值 最后给它 return 出去
let timeout, result;
//防抖函数主体
let debounced = function () {
//debounce(doSomeing,300);
let context = this; //当前执行的方法的 this ,这里是 上面绑定事件的 dom
let args = arguments; //当前执行方法里doSomeing 的 arguments
if (timeout) clearTimeout(timeout); //如果还在运动中 清除上一次的计时器
if (immediate) { //立即执行
let callNow = !timeout; //默认立即执行 默认值 true
// timeout = setTimeout 时 = true; 在等待时间后 timeout 等于null ;用户控制 callNow 变量
timeout = setTimeout(() => {
timeout = null;
}, wait);
//如果 callNow = true 执行
if (callNow) result = func.apply(context, args); //改变执行函数内部this指向 ,并传入arguments
} else { //非立即执行 事件结束后 等待时间 后执行
timeout = setTimeout(function () {
result = func.apply(context, args); //改变执行函数内部this指向 ,并传入arguments
}, wait);
}
return result;
}
//防抖函数的取消方法
debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
}
return debounced;
}
//
// 节流:
// 防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次,实现原理为设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器,
// 和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器
// 应用场景 => DOM元素拖拽 射击游戏 计算鼠标距离 scroll滚动事件
/**
* func => 绑定的方法
* wait => 间隔的时间
* {leading,trailing} 3中情况 不能同时为false
* leading => true,trailing => false, 第一次会立即执行 最后一次不会调用
* leading => false,trailing => true, 第一次不会立即执行 最后一次会调用
* leading => true,trailing => true, 第一次会立即执行 最后一次会调用
*/
function throttle(func, wait, options) {
let context, args, timeout, oldTime = 0;
if (!options) options = {};
let later = function () {
oldTime = new Date().valueOf();
timeout = null;
func.apply(context, args);
}
return function () {
conntext = this;
args = arguments;
let nowTime = new Date().valueOf();
//第一次不会立即执行
if (options.leading === false && !oldTime) {
oldTime = newTime;
}
//判断第一次进来 会不会 立即执行
if (nowTime - oldTime > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
func.apply(context, args);//间隔时间到了就可以执行
oldTime = nowTime;
}
//判断最后一次 会不会 执行
else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, wait);
}
}
}
手写js防抖和节流方法
最新推荐文章于 2024-08-25 13:14:30 发布