开发常用的防抖和节流

在前端开发过程中,会经常涉及到一些需要持续触发的事件,如:scroll,mousermove,resize,输入框监听,按钮提交等,频繁执行函数大大影响性能,利用防抖和节流可以防止一个函数被无意义的高频率调用。

防抖:当用户多次触发事件函数时,只触发最后一次操作的,其余的全部忽略掉;

节流:当持续触发事件时,保证一定时间段内只调用一次事件处理函数(避免事件在短时间内重复触发)


JavaScript版

1、鼠标移动--防抖示例
// 防抖:函数在触发事件后在n秒内函数只执行一次。如果在n秒内又触发了事件,则会重新计算函数执行时间。
<body>
    <div id="content" style="height: 350px;line-height: 350px;text-align: center;background-color: #ccc;"></div>
</body>
<script>
    let num = 1;
    let content = document.getElementById("content");
    function count() {
        content.innerHTML = "防抖:" + num++;
    }
    content.onmousemove = debounce(count);
    function debounce(fn, delay = 500) {
        let timer = null;
        return function () {
            if (timer) {
                clearTimeout(timer);
                timer = setTimeout(fn, delay);
            } else {
                timer = setTimeout(fn, delay);
            }
        }
    }
</script>

2、按钮点击事件--防抖示例
// 按钮连续点击,不会重复调用点击事件函数
<body>
    <button id="content">防抖:0</button>
</body>
<script>
    let num = 1;
    let content = document.getElementById("content");
    function count() {
        content.innerHTML = "防抖:" + num++;
    }
    content.onclick = debounce(count);
    function debounce(fn, delay = 200) {
        let timer = null;
        return function () {
            if (timer) {
                clearTimeout(timer);
                timer = setTimeout(fn, delay);
            } else {
                timer = setTimeout(fn, delay);
            }
        }
    }
</script>
3、鼠标移动--节流示例
// 节流:连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
// 如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
<body>
    <div id="content" style="height: 350px;line-height: 350px;text-align: center;background-color: #ccc;"></div> 
</body>
<script>
    let num = 1;
    let content = document.getElementById("content");
    function count() {
        content.innerHTML = "节流:" + num++;
    }
    content.onmousemove = throttle(count);
    function throttle(fn, delay = 1000) {
        let valid = true
        return function () {
            if (valid) {
                valid = false;
                setTimeout(() => {
                    fn()
                    valid = true;
                }, delay)
            } else {
                return;
            }
        }
    }
</script>

Vue版

// 防抖函数: 频繁触发、输入框搜索
<template>
    <div>
        <input type='text' v-model='value' @keydown="handelChange">
    </div>
</template>

<script>
export default {
    data() {
        return {
            value: ""
        };
    },
    methods: {
        debounce(func, wait = 1000) {
            let timeout;
            return function (event) {
                clearTimeout(timeout);
                timeout = setTimeout(() => {
                   func.call(this, event);
                }, wait);
            };
        },
        handelChange(){
            this.debounce(function (e) {
                console.log(this.value);
            });
        }
    }
};
</script>
// 节流函数:频繁触发、onrize,onscroll滚动条
<template>
    <div class="scroll" ref="previewText" @scroll.passive="fnScroll">
</template>
<script>
export default {
    data() {
        return {
            count: 0,
            fnScroll: () => {},l
        };
    },
    created() {  this.fnScroll = this.fnThrottle(this.fnHandleScroll, 1000); 
    },
    methods: {
        fnHandleScroll(e) {
            console.log("滚动触发了:" + this.count++, new Date());
        },
        fnThrottle(fn, delay, atleast) {
            //节流函数
            let timer = null;
            let previous = null;
            return function () {
                let now = +new Date();
                if (!previous) previous = now;
                if (atleast && now - previous > atleast) {
                    fn();
                    previous = now;
                    clearTimeout(timer);
                } else {
                    clearTimeout(timer);
                    timer = setTimeout(() => {
                        fn();
                        previous = null;
                    }, delay);
                }
            };
        }
    }
};
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。