• 防抖、节流函数封装(站在巨人的肩膀上)


    前情提要:

    在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。

    通常这种情况下我们怎么去解决的呢?一般来讲,防抖和节流是比较好的解决方案。

    1、新建一个 .js 文件(防抖和节流的函数封装)

    /**
    
    * @param {function} func 执行函数
    
    * @param {number} time 防抖节流时间
    
    * @param {boolean} isDebounce [1,3]为防抖组件,[2]为节流组件
    
    * @param {this} ctx this 的指向
    
    */
    
    const debounce = (func, time, isDebounce, ctx) => {
        var timer, lastCall, rtn;
        // 防抖函数
        if (isDebounce == 1) {
            rtn = (...params) => {
                if (timer) clearTimeout(timer);
                timer = setTimeout(() => {
                    func.apply(ctx, params);
                }, time);
            };
        } else if (isDebounce == 2) { // 节流函数
            rtn = (...params) => {
                const now = new Date().getTime();
                if (now - lastCall < time && lastCall) return; lastCall = now; func.apply(ctx, params);
            };
        } else if (isDebounce == 3) { 
            //立即执行的防抖函数 
            rtn = (...params) => {
                if (timer) clearTimeout(timer);
                let callNow = !timer;
                timer = setTimeout(() => {
                    timer = null;
                }, time)
                if (callNow) func.apply(ctx, params)
            };
        }
        return rtn;
    };
    
    export default {
        name: 'Debounce',
        abstract: true,
        props: {
            time: {
                type: Number,
                default: 800,
            },
            events: {
                type: String,
                default: 'click',
            },
            isDebounce: {
                type: Number,
                default: 1,
            },
        },
    
        created() {
            this.eventKeys = this.events.split(','); // 分隔事件
            this.originMap = {}; // 储存事件,用于重新render时与子事件的对比
            this.debouncedMap = {}; // 储存防抖节流事件
        },
    
        render() {
            const vnode = this.$slots.default[0];
            this.eventKeys.forEach(key => {
                const target = vnode.data.on[key];
                if (target === this.originMap[key] && this.debouncedMap[key]) {
                    vnode.data.on[key] = this.debouncedMap[key];
                } else if (target) {
                    this.originMap[key] = target;
                    this.debouncedMap[key] = debounce(
                        target,
                        this.time,
                        this.isDebounce,
                        vnode
                    );
                    vnode.data.on[key] = this.debouncedMap[key]; // 重写子组件的事件
                }
            });
            return vnode;
        },
    };
    debounceAndthrottle.js
  • 相关阅读:
    C# 调用线程并行上下文穿透-ILogicalThreadAffinative+CallContext
    C# 多线程调用静态方法或者静态实例中的同一个方法-方法内部的变量是线程安全的
    解析 .Net Core 注入——注册服务
    [Python]编码声明:是coding:utf-8还是coding=urf-8呢
    Vue加载组件、动态加载组件的几种方式
    源码版本管理工具 :TFS GIT
    Microsoft/Git-Credential-Manager-for-Mac-and-Linux
    SqlServer 对分组的内容进行拼接-group_concat
    MFC中页面设置对话框CPageSetupDialog
    MFC中查找替换对话框CFindReplaceDialog类
  • 原文地址:https://www.cnblogs.com/meiyanstar/p/14816452.html
Copyright © 2020-2023  润新知