JavaScript基础计时器方法

2022-08-19 08:08:19

一、setInterval()与clearInterval()

<body>
    <button class="btn">暂停</button>
    <script>
        let timer = setInterval(function () {
            console.log("hello world");
        }, 1000)

        let btn = document.querySelector(".btn");
        btn.onclick = function () {
            clearInterval(timer);
        }
    </script>
</body>

效果如下:

分析:

可以给setInterval设置一个返回值timer

那么就可以使用clearInterval(timer),来终止计时器

二、案例一——显示当前时间

<body>
    <h1></h1>
    <script>
        let h1 = document.querySelector("h1");
        setInterval(function () {
            let time = new Date();
            let hours = time.getHours();
            let minutes = time.getMinutes();
            let seconds = time.getSeconds();
            h1.innerHTML = `${hours}:${minutes}:${seconds}`;
        }, 1000)
    </script>
</body>

效果如下:

分析:

每隔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>Demo27</title>
</head>

<body>
    <button class="start">开始</button>
    <button class="pause">暂停</button>
    <button class="stop">重置</button>
    <h1></h1>
    <script>
        let start = document.querySelector(".start");
        let pause = document.querySelector(".pause");
        let stop = document.querySelector(".stop");
        let h1 = document.querySelector("h1");
        let seconds = 0;
        let ms = 0;
        h1.innerHTML = `${seconds}:${ms}`;

        let timer = null;

        start.onclick = function () {
            // 重复点击开始按钮时,先停止上一次的计时器
            clearInterval(timer);
            timer = setInterval(() => {
                if (ms === 9) {
                    ++seconds;
                    ms = 0;
                }
                ++ms;
                h1.innerHTML = `${seconds}:${ms}`;
            }, 100);
        }

        pause.onclick = function () {
            clearInterval(timer);
        }

        stop.onclick = function () {
            clearInterval(timer);
            seconds = 0;
            ms = 0;
            h1.innerHTML = `${seconds}:${ms}`;
        }
    </script>
</body>

</html>

效果如下:

四、setTimeout和clearTimeout

<body>
    <h1>5秒后,跳转到百度...</h1>
    <script>
        setTimeout(() => {
            location.href = "https://www.baidu.com";
        }, 5000)
    </script>
</body>

效果如下:

分析:

location.href:表示跳转到其他链接。

setTimeout():表示,过多少秒后,执行方法。

五、防抖与节流

1、提出问题

某些事件,在短时间内会触发很多次。这极大的影响了性能。

比如window.onscroll事件,如下:

<!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>Demo29</title>
    <style>
        body {
            height: 2000px;
        }
    </style>
</head>

<body>
    <h1>windows.onscroll</h1>
    <script>
        window.onscroll = function(){
            console.log("hello world");
        }
    </script>
</body>

</html>

效果如下:

如图所示,鼠标滚轮轻轻滚动,事件在短时间内触发了很多次

如何解决呢?

2、防抖

<!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>Demo29</title>
    <style>
        body {
            height: 2000px;
        }
    </style>
</head>

<body>
    <h1>windows.onscroll</h1>
    <!-- 防抖 -->
    <script>
        let timer = null;
        window.onscroll = function () {
            // timer(计时器)不为空时,则让它停止
            if (timer != null) {
                clearTimeout(timer);
            }

            // 鼠标滚动一次,则立马执行计时器
            // 计时器启动时,timer就不为空,则立马停止,并且打印,并且将timer置为空
            timer = setTimeout(() => {
                console.log("hello world");
                timer = null;
            }, 500)
        }
    </script>
</body>

</html>

效果如下:

效果分析:

在0.5秒内,如果多次滚动滚轮,则不会重复执行事件。

停止滚动时,才执行事件。

代码分析:

鼠标滚动时,启动计时器,0.5秒后,执行事件。也就是说,0.5秒内,setTimeout内的代码没有执行。

此时,timer不为空了。就会把上一次的计时器(或者可以称作延时器)清除掉,并且鼠标持续滚动,也就是持续地开启下一个计时器

直到我们停止滚轮滚动,清除计时器的代码不再执行,就只执行最后一次(上一次的计时器没有清除掉)的代码

并且将timer置为空,下次可以再次使用。

从而实现防抖功能。

一次都不会执行。

 3、节流

    <!-- 节流 -->
    <script>
        let mark = true;
        window.onscroll = function () {
            if (mark) {
                setTimeout(() => {
                    console.log("hello world");
                    mark = true;
                }, 500)
            }
            mark = false;
        }
    </script>

效果如下:

效果分析:

当我们持续滚动滚轮时,每隔0.5秒,照样会执行事件

当我们停止滚动时,最后再执行一次,则停止执行事件

 代码分析:

设个标记mark,初值为true。

滚轮滚动时,开启计时器,0.5秒后执行事件。

随后,mark被置为false。此时不再进入if方法。

然而,0.5秒后,事件启动,并且mark再次被置为true。因为滚轮持续在滚动,则,再一次进入if方法。从而开启下一个计时器。

这样就达到每0.5秒都执行一次事件。

4、案例——返回顶部(利用闭包封装算法)

<!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>Demo30</title>
    <style>
        body {
            height: 2000px;
        }

        button {
            position: fixed;
            right: 100px;
            bottom: 100px;
            display: none;
        }
    </style>
</head>

<body>
    <h1>hello world</h1>
    <button>⬆</button>

    <script>
        let btn = document.querySelector("button");
        btn.onclick = function () {
            window.scrollTo(0, 0);
        };

        // 防抖
        function debounce(fn) {
            let timer = null;
            function eventFun() {
                if (timer != null) {
                    clearTimeout(timer);
                }
                timer = setTimeout(() => {
                    fn();
                    timer = null;
                }, 500)
            }
            return eventFun;
        }

        // 节流
        function throttle(fn) {
            let mark = true;
            // 直接返回函数也可以
            return function () {
                if (mark) {
                    setTimeout(() => {
                        fn();
                        mark = true;
                    }, 500)
                }
                mark = false;
            }
        }

        window.onscroll = debounce(() => {
            console.log("计数器");
            if (document.documentElement.scrollTop > 0) {
                btn.style.display = "block";
            } else {
                btn.style.display = "none";
            }
        });
    </script>
</body>

</html>

分析:

实现的是一个:网页中的返回顶部功能。

其中使用到了防抖/节流

通过闭包将防抖/节流算法封装起来。

 input输入框,停下来时才去识别,这也可以使用防抖。

  • 作者:pro1822
  • 原文链接:https://blog.csdn.net/qq_41523175/article/details/124178973
    更新时间:2022-08-19 08:08:19