1. 程式人生 > 其它 >前端面試題整理——手寫防抖和節流

前端面試題整理——手寫防抖和節流

防抖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;
            width: 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;
            width: 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>