前端优化中的防抖与截流
Posted aiguangyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端优化中的防抖与截流相关的知识,希望对你有一定的参考价值。
1. 什么是防抖?
在事件触发后的指定时间之后,再去执行真正需要执行的函数,如果在该时间之内事件又被触发,则重新开始计时。
常见的应用场景:
1. 滚动事件触发;
2. 搜索框输入查询;
3. 表单验证;
4. 按钮提交事件;
5. 浏览器窗口缩放;
以下是代码实现:
function debounce(func, time, immediate)
// 用来获取返回值
let timer, result;
let debounced = function ()
// 保存当前指向
let that = this;
// 获取函数的参数
let args = arguments;
// 清除当前定时器
clearTimeout(timer);
// 立即执行
if (immediate)
let callNow = !timer;
// 指定时间内不再执行
timer = setTimeout(function ()
timer = null;
, time);
if (callNow)
result = func.call(that, ...args);
;
// 不立即执行
else
// 指定时间后触发函数
timer = setTimeout(function ()
// 改变函数内部指向,并传递参数
func.call(that, ...args);
, time);
;
return result;
;
// 取消函数
debounced.cancel = function ()
// 清除定时器
clearTimeout(timer);
// 定时器置空
timer = null;
;
// 返回防抖函数
return debounced;
2. 什么是截流?
在指定时间内触发多次函数的话,只有一次是可被执行的,下一次执行只能等到下一个周期里。
常见的应用场景:
1. DOM元素的拖拽功能实现;
2. 射击游戏;
3. 计算鼠标的移动距离;
4. 监听滚动事件;
截流函数根据是否立即执行,操作完成后是否还会执行一次,分为三种情况:
1. 用时间戳来实现。第一次立即执行,操作完成后不再执行;
function throttle(func, time)
let that, args;
let old = 0;
return function ()
// 获取当前的时间戳
let now = new Date().valueOf();
// 保存当前指向
that = this;
// 获取函数的参数
args = arguments;
if (now - old > time)
// 改变函数内部指向,并传递参数
func.apply(that, args);
// 更新旧时间戳
old = now;
;
2. 用定时器实现节流函数。第一次延时执行,操作完成后还会执行一次;
function throttle(func, time)
let that, args, timer;
return function ()
// 保存当前指向
that = this;
// 获取函数的参数
args = arguments;
if (!timer)
timer = setTimeout(function ()
timer = null;
func.apply(that, args);
, time);
;
3. 用时间戳与定时器结合实现截流函数。第一次立即执行,操作完成后还会执行一次;
function throttle(func, time)
let that, args, timer;
let old = 0;
return function ()
// 保存指向
that = this;
args = arguments;
let now = new Date().valueOf();
if (now - old > time)
if (timer)
clearTimeout(timer);
timer = null;
func.apply(that, args);
old = now;
;
if (!timer)
timer = setTimeout(function ()
// 更新最新的时间戳
old = new Date().valueOf();
timer = null;
func.apply(that,args);
, time);
最终版,用时间戳与定时器结合实现截流函数。根据参数来决定开始是否立即执行,结束后是否还会执行。
function throttle(func, time, options)
let that, args, timer;
// 设置初始时间戳
let old = 0;
// 如果没有该参数,置为空对象
if(!options)options = ;
return function ()
that = this;
args = arguments;
// 获取初始的时间戳
let now = new Date().valueOf();
// leading为false表示不立即执行
if (options.leading === false && !old)
old = now;
;
if (now - old > time)
if (timer)
clearTimeout(timer);
timer = null;
func.apply(that, args);
old = now;
;
// trailing为true表示最后一次会被执行
if (!timer && options.trailing==true)
timer = setTimeout(function ()
// 更新最新的时间戳
old = new Date().valueOf();
timer = null;
func.apply(that,args);
, time);
以上是关于前端优化中的防抖与截流的主要内容,如果未能解决你的问题,请参考以下文章