防抖,单位时间内,频繁触发,只执行最后一次
效果演示
-
优化前,不断触发,浪费性能
-
优化后,只在指定时间内触发
演示代码
import debounce from "/node_modules/lodash-es/debounce.js";
const oBox = document.getElementById("box");
let index = 0;
function move() {this.innerHTML = index++;
}//默认进来调用一次
move.call(oBox);
//使用防抖
oBox.addEventListener("mousemove", debounce(move, 1000));
//不使用防抖
// oBox.addEventListener("mousemove", move);//自己封装的防抖
function _debounce(fn, delay) {clearTimeout(this.timeId);this.timeId = setTimeout(() => {move.call(this);}, 1000);
}
#box{width: 100px;height: 100px;background: red;color:#fff;text-align: center;cursor: pointer;}
<div id="box"></div>
封装优化
function _debounce(fn, delay) {//默认进来调用一次move.call(oBox);return function () {clearTimeout(fn.timeId);fn.timeId = setTimeout(() => {move.call(this);}, delay);};
}
节流,单位时间内,频繁触发,只执行第一次,期间触发不执行,500s再执行
窗口大小改变时的布局调整:当用户快速调整窗口大小时,节流可以确保在每个时间段内只执行一次布局调整操作,避免过度渲染。
滚动事件的处理:滚动事件可能会非常频繁地触发,节流可以限制滚动事件处理器的执行频率,提高性能。
使用场景: 比如: 监听滚动条,每隔一段时间计算一次位置
在定时器里面是无法清除定时器的,这是一个bug,在定时器外面可以清除
,所以必须手动重置为null
封装节流
oBox.addEventListener("mousemove", _throttle(move, 500));function _throttle(fn, delay) {//默认进来调用一次fn.call(oBox);const mowTime = Date.now();return function () {if (fn.timeId) return;fn.timeId = setTimeout(() => {fn.call(this);// 在定时器里面是无法清除定时器的,这是一个bug,在外面可以清除clearTimeout(fn.timeId);// fn.timeId = null;}, delay);};
}
function _throttle2(fn, delay) {let now = Date.now();// 第一次进来,直接执行fn.call(oBox);// 第二次进来,判断是否超过了规定时间// 超过了规定时间,执行return function () {const t = Date.now() - now - delay;if (t >= 0) {fn.call(this);now = Date.now();}};
}
不手动重置定时器,触发是没反应的