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

上面说到的这些动画特效中,其实就用到了 “定时器”。所谓的 “定时器”,指的是每隔一段时间就执行一次代码。在 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 个参数是一个函数,这个函数是没有名字的,也叫匿名函数。

示例 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 个参数是一个函数名,这个函数名是不需要加括号 () 的!实际上,下面 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>页面效果如下图所示。

分析:
当我们点击【开始】按钮,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>页面效果如下图所示。

分析:
如果这里使用 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>页面效果如下图所示。

分析:
当我们点击【开始】按钮后,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>页面效果如下图所示。

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