JavaScript 定时器

在浏览器网页的过程中,我们经常可以看到这样的动画:比如轮播效果中,图片每隔几秒就切换一次;在线时钟中,秒针每隔一秒转一次。

JavaScript 定时器实现在线时钟

上面说到的这些动画特效中,其实就用到了 “定时器”。所谓的 “定时器”,指的是每隔一段时间就执行一次代码。在 JavaScript 中,实现定时器主要有以下 2 组函数。

  • setTimeout() 和 clearTimeout()
  • setInterval 和 clearInterval()

JavaScript setTimeout() 和 clearTimeout()

在 JavaScript 中,我们可以使用 setTimeout() 函数定义一个 “只执行一次” 的定时器,并且可以使用 clearTimeout() 来取消执行 setTimeout()。

语法:

setTimeout(code, delay, arg1, arg2, ..., argN)

说明:

setTimeout() 函数接收以下 3 种参数。

  • code(必选):可以是一段代码(字符串),可以是一个函数,也可以是一个函数名。
  • delay(可选):是时间,单位为毫秒,表示要过多长时间才执行 code 中的代码。
  • arg1, arg2, ..., argN(可选):只有当 code 是一个函数时才会生效,此时表示传递给回调函数 code 的附加参数。

setTimeout() 会返回一个唯一的 ID(整数),用于将来取消该定时器。

示例 1:code 是一个函数

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <p>2 秒后提示欢迎语。</p>
    <script>
        setTimeout(function () {
            alert("欢迎来到绿叶网!");
        }, 2000);
    </script>
</body>
</html>

默认情况下,页面效果如下图 1 所示。打开页面 2 秒后,会弹出对话框,如下图 2 所示。

setTimeout() 第一个参数是函数(1)

setTimeout() 第一个参数是函数(2)

分析:

在这个例子中,setTimeout() 的第 1 个参数是一个函数,这个函数是没有名字的,也叫匿名函数。

setTimeout() 第一个参数是匿名函数

示例 2:code 是一个函数名

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <p>2 秒后提示欢迎语。</p>
    <script>
        function welcome(){
            alert("欢迎来到绿叶网!");
        }
        setTimeout(welcome, 2000);
    </script>
</body>
</html>

默认情况下,页面效果如下图 1 所示。打开页面 2 秒后,会弹出对话框,如下图 2 所示。

setTimeout() 第一个参数是函数名(1)

setTimeout() 第一个参数是函数名(2)

分析:

在这个例子中,setTimeout() 第 1 个参数是一个函数名,这个函数名是不需要加括号 () 的!实际上,下面 2 种写法是等价的:

// 写法 1
setTimeout(welcome, 2000);

// 写法 2
setTimeout("welcome()", 2000);

之前接触过不少初学者,很多小伙伴很容易搞混这两个写法,比如如写成 setTimeout(welcome(), 2000) 或者 setTimeout("welcome", 2000),我们一定要注意这一点。

对于初学的小伙伴来说,我们只需要掌握 setTimeout(welcome, 2000) 这一种写法就可以了,原因有 2 个:一是这种写法性能更高;二是可以避免多种写法造成记忆混乱。

示例 3:使用 clearTimeout()

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <p>点击“开始”按钮,2 秒后提示欢迎语。</p>
    <button id="start">开始</button>
    <button id="pause">暂停</button>
    <script>
        const oStart = document.getElementById("start");
        const oPause = document.getElementById("pause");
        let timer = null;    // timer存放定时器

        oStart.addEventListener("click", function() {
            timer = setTimeout(function() {
                alert("欢迎来到绿叶网!");
            }, 2000);
        });

        oPause.addEventListener("click", function() {
            clearTimeout(timer);
        });
    </script>
</body>
</html>

页面效果如下图所示。

JavaScript clearTimeout() 示例

分析:

当我们点击【开始】按钮,2 秒后就会弹出对话框。如果在 2 秒内迅速点击【暂停】按钮,就不会弹出对话框。

这里定义了一个变量 timer 用于保存 setTimeout() 这个定时器,以便使用 clearTimeout(timer) 来暂停。

JavaScript setInterval() 和 clearInterval()

在 JavaScript 中,我们可以使用 setInterval() 函数来定义一个 “重复执行” 的定时器,然后可以使用 clearInterval() 来取消执行 setInterval()。

语法:

setInterval(code, time);

说明:

setInterval() 函数接收以下 3 种参数。

  • code(必选):可以是一段代码,可以是一个函数,也可以是一个函数名。
  • delay(可选):是时间,单位为毫秒,表示要过多长时间才执行 code 中的代码。
  • arg1, arg2, ..., argN(可选):只有当 code 是一个函数时才会生效,此时表示传递给回

setInterval() 跟 setTimeout() 语法是一样的,唯一不同的是:setTimeout() 只执行一次;而 setInterval() 可以重复执行无数次。

对于 setInterval() 来说,下面 3 种写法都是可行的(与 setTimeout() 一样)。一般情况下,我们只需要掌握前 2 种即可。

// 方式1
setInterval(function(){…}, 2000)

// 方式2
setInterval(welcome, 2000)

// 方式3
setInterval("welcome()", 2000)

示例 4:setInterval() 实现倒计时效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <p>倒计时:<span id="num">10</span></p>
    <script>
        // 定义全局变量,用于记录秒数
        let n = 10;

        //定义函数
        function countDown() {
            const oNum = document.getElementById("num");
            //判断 n 是否大于 0,因为倒计时不能是负数
            if (n > 0) {
                n--;
                oNum.textContent = n;
            }
        }

        // 设置定时器,重复执行函数 countDown
        setInterval(countDown, 1000);
    </script>
</body>
</html>

页面效果如下图所示。

JavaScript setInterval() 实现倒计时

分析:

如果这里使用 setTimeout() 来代替 setInterval(),就没办法实现倒计时效果了。因为 setTimeout() 只会执行一次,而 setInterval() 可以重复执行。

示例 5:clearInterval() 清除定时器

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        div {
            width: 100px;
            height: 100px;
            margin-top: 10px;
            border: 1px dashed gray;
        }
    </style>
</head>
<body>
    <button id="start">开始</button>
    <button id="pause">暂停</button>
    <div></div>
    <script>
        // 获取元素
        const oDiv = document.getElementsByTagName("div")[0];
        const oStart = document.getElementById("start");
        const oPause = document.getElementById("pause");

        // 定义一个数组,存放 6 种颜色
        const colors = ["red", "orange", "yellow", "green", "blue", "purple"];
        // timer用于保存定时器
        let timer = null;
        // i用于计数
        let i = 0;

        // “开始” 按钮
        oStart.onclick = function () {
            //每隔 1 秒切换一次背景颜色
            timer = setInterval(function () {
                oDiv.style.backgroundColor = colors[i];
                i++;
                i = i % colors.length;
            }, 1000);
        };

        // “暂停” 按钮
        oPause.onclick = function () {
            clearInterval(timer);
        };
    </script>
</body>
</html>

页面效果如下图所示。

JavaScript clearInterval() 示例

分析:

当我们点击【开始】按钮后,div 元素每隔 1 秒就会切换一次背景颜色。当我们点击【暂停】按钮,就会停止。i = i % colors.length; 使得 i 可以不断循环 0、1、2、3、4、5,这是一个非常棒的技巧,特别是在图片轮播开发中非常有用,小伙伴们认真琢磨一下。

当我们快速多次地点击【开始】按钮,神奇的一幕发生了:背景颜色切换的速度加快了。然后点击【暂停】按钮,却发现根本停不下来!那是什么原因导致的呢?

其实每一次点击,都会新开一个 setInterval(),当你不断点击按钮,setInterval() 就会累加起来。也就是说,当你点击 3 次按钮时,其实已经开了 3 个 setInterval(),此时如果你想要停下来,就必须点击 3 次【暂停】按钮。为了避免这个累加的 bug,我们在每次点击【开始】按钮的一开始就要清除一次定时器,改进后的代码如下。

示例 6:改进后的定时器

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        div {
            width: 100px;
            height: 100px;
            margin-top: 10px;
            border: 1px dashed gray;
        }
    </style>
</head>
<body>
    <button id="start">开始</button>
    <button id="pause">暂停</button>
    <div></div>
    <script>
        // 获取元素
        const oDiv = document.getElementsByTagName("div")[0];
        const oStart = document.getElementById("start");
        const oPause = document.getElementById("pause");

        // 定义一个数组,存放 6 种颜色
        const colors = ["red", "orange", "yellow", "green", "blue", "purple"];
        // timer用于保存定时器
        let timer = null;
        // i用于计数
        let i = 0;

        // “开始” 按钮
        oStart.onclick = function () {
            // 每次点击 “开始” 按钮,在一开始就清除一次定时器
            clearInterval(timer);

            //每隔 1 秒切换一次背景颜色
            timer = setInterval(function () {
                oDiv.style.backgroundColor = colors[i];
                i++;
                i = i % colors.length;
            }, 1000);
        };

        // “暂停” 按钮
        oPause.onclick = function () {
            clearInterval(timer);
        };
    </script>
</body>
</html>

页面效果如下图所示。

JavaScript 改进后的定时器

分析:

此时即使我们快速不断地点击【开始】按钮,也不会出现定时器累加的 bug 了。定时器在实际开发中会大量用到,小伙伴们要重点掌握。

上一篇: JavaScript 对话框

下一篇: JavaScript 对象

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号