IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端优化中的防抖与截流 -> 正文阅读

[JavaScript知识库]前端优化中的防抖与截流

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);
        }
    }
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 11:40:51  更:2022-05-13 11:42:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:59:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码