前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端优化中的防抖与截流

前端优化中的防抖与截流

作者头像
越陌度阡
发布2022-05-11 08:57:25
4160
发布2022-05-11 08:57:25
举报

1. 什么是防抖?

在事件触发后的指定时间之后,再去执行真正需要执行的函数,如果在该时间之内事件又被触发,则重新开始计时。

常见的应用场景:

1. 滚动事件触发

2. 搜索框输入查询

3. 表单验证

4. 按钮提交事件

5. 浏览器窗口缩放

以下是代码实现:

代码语言:javascript
复制
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. 用时间戳来实现。第一次立即执行,操作完成后不再执行。

代码语言:javascript
复制
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. 用定时器实现节流函数。第一次延时执行,操作完成后还会执行一次。

代码语言:javascript
复制
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. 用时间戳与定时器结合实现截流函数。第一次立即执行,操作完成后还会执行一次。

代码语言:javascript
复制
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);
        }
    }
}

最终版,用时间戳与定时器结合实现截流函数。根据参数来决定开始是否立即执行,结束后是否还会执行。

代码语言:javascript
复制
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);
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是防抖?
  • 2. 什么是截流?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档