JavaScript之防抖和节流的使用

52 阅读1分钟

​​本文已参与「新人创作礼」活动,一起开启掘金创作之路

 本文主要介绍JavaScript中防抖和节流的使用。

1.防抖

核心:防止密集执行,每次触发重新计时

示例代码如下:

鼠标移入该盒子后,会触发1秒的定时器,在此1秒内,若重复触发,则重新开始计时。1秒过后才能触发下一次操作。

效果:当一直进行触发时,会一直重新计时,看不到效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 防抖:重新计时 -->
    <style>
        div {
            width: 500px;
            height: 500px;
            background-color: skyblue;
            text-align: center;
            line-height: 500px;
            margin: 100px auto;
            font-size: 100px;
            user-select: none;
        }
    </style>
</head>

<body>
    <div>0</div>
    <script>
        let num = 0;
        let timeout = true;
        document.querySelector('div').addEventListener('mousemove', function() {
            if (timeout) {
                clearTimeout(timeout);
                timeout = setTimeout(() => {
                    num++;
                    this.innerHTML = num
                }, 1000)
            }
        })
    </script>
</body>

</html>

 2.节流

核心:固定时间内只执行1次

示例代码如下:

本例通过两个ul来比较设置节流与未设置节流的区别。利用了函数闭包的思想。当第一次触发时,会设置一个定时器,同时将判断条件设为不成立,故在此时间内其他的触发都不会执行。直到此定时器运行完成,会将条件设为成立,从而可以进行下一次触发。

效果:当一直触发时,相当于每隔一定时间执行一次函数,在间隔内的触发都无效。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #ul1 {
            float: left;
        }
        
        #ul2 {
            float: left;
        }
        
        ul {
            width: 100px;
        }
    </style>
    <!-- 
节流:执行一次
     -->
</head>

<body>
    <div>
        <ul id="ul1"></ul>
        <ul id="ul2"></ul>
    </div>
    <script>
        // 未设置节流
        window.addEventListener('mousemove', function() {
            let li = document.createElement('li');
            li.innerHTML = '1';
            document.querySelector('#ul1').appendChild(li);
        })

        // 设置了节流。运行程序会调用throttle函数,滑动触发之后调用return中的函数。
        // 执行机制:timeout初始为null,滑动则触发计时器,timeout变为非空,直到定时器执行完成才能再次触发。
        window.addEventListener('mousemove', throttle(log1, 50))


        function log1() {
            let li = document.createElement('li');
            li.innerHTML = '2';
            document.querySelector('#ul2').appendChild(li);
        }

        function throttle(fun, wait) {
            let timeout = null;
            console.log(1);
            return function() {
                console.log(2);
                if (!timeout) {
                    timeout = setTimeout(() => {
                        fun();
                        timeout = null;
                    }, wait)
                }
            };
        }
    </script>
</body>

</html>

\