chst365's blog chst365's blog
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

chst365

DIV工程师
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 浏览器

  • webpack

  • TypeScript

  • 性能

  • 工程化

  • React

  • JavaScript

  • 编程题

    • 实现一个trim方法
    • 实现一个deepClone方法
    • 实现add(1)(2)(3)
    • 大数相加
    • 拍平数组flat
    • 实现防抖、节流函数
      • 防抖
        • 防抖原理
        • 注意点
      • 节流
        • 节流原理及实现方案
        • 注意点
    • 反转字符串
    • 数组去重
    • 实现千位分隔符
    • 回文数
    • 实现一个模板引擎
    • 判断一个数是否是素数
    • 获取n以内所有的素数
  • React技术揭秘

  • 算法

  • 前端
  • 编程题
chst365
2022-09-02
目录

实现防抖、节流函数

在前端开发中会遇到一些频繁的事件触发,如

  1. window的resize、scroll
  2. mousedown、mousemove
  3. keyup、keydown 我们不想让他频繁触发,如表单的提交,一定时间内我们只希望它提交一次而非多次。于是,就出现了防抖和节流。

# 防抖

# 防抖原理

你尽管触发事件,但在事件触发n秒后才执行;若一个事件触发后的n秒内又重新触发此事件,以新事件的时间为准,n秒后才执行。

# 注意点

  • this 指向问题 this会指向window对象而非指向正确的对象
  • event 对象问题 event对象获取为undefined
  • 立即执行 立即执行函数,然后等到停止触发n秒后,才可重新触发执行
  • 返回值 函数可能有返回值,当不立即执行的时候,因使用了定时器,函数的返回值赋给变量,最后return时,值会一直是undefined,所以只在立即执行的时候返回函数的执行结果
  • 取消 有时候,我们设置等待的时间有点长,可能需取消防抖。即给防抖函数加一个取消的功能
function debounce(func, wait, immediate) {
    var timeout, result;
    var debounced = function () {
        // this 指向错误问题
        var context = this;
        // event 对象获取为undefined
        var args = arguments;
        if (timeout) clearTimeout(timeout);
        // 立即执行
        if (immediate) {
            // 如果已经执行过,不再执行
            var callNow = !timeout;
            timeout = setTimeout(function () {
                timeout = null;
            }, wait);
            // 返回值
            if (callNow) result = func.apply(context, args);
        } else {
            timeout = setTimeout(function () {
                func.apply(context, args);
            }, wait);
        }
        return result;
    };
    // 加取消功能
    debounced.cancel = function () {
        clearTimeout(timeout);
        timeout = null;
    };
    return debounced;
}

// 使用
var debounceFunc = debounce(func, 10000, true)
debounceFunc.cancel()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 节流

# 节流原理及实现方案

原理:若你持续触发事件,每隔一段时间,只执行一次事件。 方案:时间戳、设置定时器

# 注意点

  • 使用时间戳 当触发事件时,取当前时间戳,减去之前的时间戳(初始值为0),若 > 设置的时间周期,执行函数,更新时间戳为当前时间戳;若 < ,不执行。
  • 使用定时器 当事件触发时,设一定时器,再次触发时,若定时器存在,就不执行;直到定时器执行完,执行函数,清空定时器,设置下个定时器
  • 无头有尾或有头无尾
  • 取消
function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};
    var later = function () {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };
    var throttled = function () {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };
    throttled.cancel = function () {
        clearTimeout(timeout);
        previous = 0;
        timeout = null;
    };
    return throttled;
}

// leading:false 和 trailing: false 不能同时设置。
container.onmousemove = throttle(getUserAction, 1000);
container.onmousemove = throttle(getUserAction, 1000, {
    leading: false
});
container.onmousemove = throttle(getUserAction, 1000, {
    trailing: false
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#前端#编程题
上次更新: 2022/09/02, 17:10:06
拍平数组flat
反转字符串

← 拍平数组flat 反转字符串→

最近更新
01
面试官
03-27
02
this&指针&作用域&闭包
03-27
03
前端
03-27
更多文章>
Theme by Vdoing | Copyright © 2019-2025 chst365 | 豫ICP备17031889号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式