防抖
防抖,即如果短时间内大量触发同一事件,都会重置计时器,等到事件不触发了,再等待规定的时间,才会执行函数。
* 规定时间内,只触发一次
应用场景:
scroll事件滚动触发
搜索框输入查询
表单验证
按钮提交事件
浏览器窗口缩放,resize事件
function debounce(fn, delay = 500, immediate) {
// 1、创建一个标记用来存放定时器的返回值
let timeout = null;
return function() {
// 2、每次当用户点击(timeout 有定义)的时候,清除前一个定时器
if (timeout) clearTimeout(timeout);
// 3、创建一个新的 setTimeout,这样就能保证点击按钮后的 delay 间隔内,如果用户还点击了的话,就不会执行 fn 函数
const [that, args] = [this, arguments];
if(immediate){ // 立即执行
let callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, delay);
if (callNow) fn.apply(that, args);
}else{ // 非立即执行
timeout = setTimeout(() => {
fn.apply(that, args);
}, delay);
};
};
}
// 调用:
<a href="javascript:;" id="btn">防抖</a>
let btn = document.getElementById('btn');
btn.addEventListener('click', this.debounce(this.chenhf, 1000, false));
节流
节流,即在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效
* 每隔一段时间 只 执行一次
应用场景:
dom元素的拖拽功能实现
射击游戏
计算鼠标移动的距离
监听scroll滚动事件
时间戳版:
function throttle(fn, delay) {
let previous = 0;
return function() {
const [that, args] = [this, arguments];
let now = Date.now();
if (now - previous > delay) {
fn.apply(that, args);
previous = now;
}
}
}
定时器版:
function throttle(fn, delay) {
let timeout = null;
return function() {
const [that, args] = [this, arguments];
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
fn.apply(that, args);
}, delay);
}
}
}
合并:
function throttle(fn, delay, type) {
let previous,timeout;
if(type === 1){ // 时间戳版
previous = 0;
}else if(type === 2){ // 定时器版
timeout = null;
}
return function() {
const [that, args] = [this, arguments];
if(type === 1){ // 时间戳版
let now = Date.now();
if (now - previous > delay) {
fn.apply(that, args);
previous = now;
}
}else if(type === 2){ // 定时器版
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
fn.apply(that, args)
}, delay)
}
}
}
}
// 调用:
<a href="javascript:;" id="btn">防抖</a>
let btn = document.getElementById('btn');
btn.addEventListener('click', this.throttle(this.chenhf, 1000, 1));
网友评论