前端面试题整理——手写防抖和节流

防抖debounce:

防抖是在定义N的时间范围内,如果没有触发事件则执行,如果触发了时间重置进行下一轮判断。

使用场景例如一个输入框有搜索功能,当键盘输入停止了一段时间,判定用户结束或暂停输入,然后再进行接口搜索,避免每次输入都进行一次接口调用。

手写防抖函数:

<input type="text" id="input1" />
<!-- 没有封装的写法 -->
<script>
        let input1 = document.getElementById("input1");
        let timer = null
        input1.addEventListener("keyup", function () {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function () {
                console.log(input1.value);
                timer = null
            }, 500)
        }, false);
</script>

  

    <input type="text" id="input1" />
    <script>
        // 封装防抖函数
        let input1 = document.getElementById("input1");
        input1.addEventListener('keyup', debounce(() => {
            console.log(input1.value);
        }), false)

        function debounce(fn, time = 500) {
            let timer = null
            return function () {
                if (timer) {
                    clearTimeout(timer);
                }
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                }, time)
            }
        }
    </script>

  

节流throttle:

节流是连续触发事件,但是在N的时间里只进行一次触发,避免过度频繁触发事件。

使用场景例如拖拽DIV移动可以间隔一定时间进行移动的触发。

手写节流函数

<style>
        #div1 {
            border: 1px solid #000;
             100px;
            height: 100px;
        }
    </style>
    <div id="div1" draggable="true"></div>
    <script>
        // 不做封装
        let div1 = document.getElementById('div1');
        let timer = null;
        div1.addEventListener('drag', function (e) {
            if (timer) return
            timer = setTimeout(function () {
                console.log(e.offsetX, e.offsetY)
                timer = null
            }, 100)
        }, false)
    </script>

  

    <style>
        #div1 {
            border: 1px solid #000;
             100px;
            height: 100px;
        }
    </style>
    <div id="div1" draggable="true"></div>
    <script>
        // 进行封装
        let div1 = document.getElementById('div1');
        div1.addEventListener('drag', throttle((e) => {
            console.log(e.offsetX, e.offsetY)
        }), false)

        function throttle(fn, time = 100) {
            let timer = null;
            return function () {
                if (timer) return
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                }, time)
            }
        }
    </script>

  

放弃安逸,持续努力——成长
原文地址:https://www.cnblogs.com/MarsPGY/p/14946462.html