节流
-
何为节流?
定义:节流 (throttle): 高频事件在规定时间内只会执行一次,执行一次后,只有大于设定的执行周期后才会执行第二次。
也就是说,让需要频繁触发的事件按照指定的时间间隔进行多次触发 -
什么时候需要用?
从性能优化的角度考虑,不需要那么高频的触发,需要限制一下时, 可使用节流
应用场景有:
-
DOM 元素的拖拽功能实现(mousemove);
-
射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹);
-
计算鼠标移动的距离(mousemove);
-
Canvas 模拟画板功能(mousemove);
-
搜索联想(keyup);
-
监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次。
- 实现代码
// 你要多次触发的函数
const fn = function() {
console.log('scroll')
};
// 节流函数
function throttle(fn, time) {
let timer = null;
let startTime = new Date(); // 初始调用的时间
return function () {
let args = [].slice.call(arguments);
// 当前的时间 - 开始时间 是否大于指定的时间差
timer = (new Date() - startTime) >= time;
if (timer) {
fn.apply(this, args);
startTime = new Date();
}
}
}
const f = throttle(fn, 300);
//window.onscroll = fn;
window.onscroll = f;
防抖
-
何为防抖?
定义: 防抖 (debounce): n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。
也就是说,事件是需要可多次触发的, 但只有在距离上次触发的时间大于指定时间时,才会触发事件(在指定时间只允许执行一次) -
什么时候需要用?
应用场景有 :
①窗口的resize
②当输入框input输入时需要进行联想时,我们会监听keyup事件,更可能需要调用联想词的接口,这时我们该思考了,真的需要每按一个按键就触发一次调用联想词吗?实际上是不需要的,用户迅速的输入时,就频繁的调接口是一种浪费。使用防抖,可以限制一个方法在一定时间内执行的次数,有效的提高了网站性能
③一个元素的onmouseover事件,或滚动事件,或其他执行得非常迅速的高频触发事件 -
实现代码
const fn = function() {
console.log('scroll')
};
// 防抖函数
function debounce(fn, time) {
let timer = null;
return function () {
var _this = this;
let args = [].slice.call(arguments);
clearTimeout(timer)
timer = setTimeout(function () {
fn.apply(_this, args);
}, time)
}
}
window.onscroll = debounce(fn, 300);