主题
1-14函数综合案例
本页对应 第一章JavaScript基础,共 2 段视频,约 17 分钟。
学习目标
- 能够使用
prompt获取用户输入的总秒数,并通过+将其转换为数字型后保存到变量中。 - 能够封装并调用
getTime(t)函数,将总秒数作为实参传入,并在函数形参中接收处理。 - 能够使用取整与取余公式将总秒数换算为小时、分钟、秒,并正确赋值给对应变量。
- 能够使用三元表达式对小时、分钟、秒进行小于 10 补零操作,输出两位数字格式。
- 能够通过
return返回包含三个span标签的模板字符串,并将计算后的时分秒数据替换到对应位置。 - 能够将返回的带标签字符串渲染到页面指定容器中,并使用 61 秒、1000 秒等输入验证转换与显示结果。
知识点
需求与效果

为什么需要:学完函数后,需要用一个小案例把“输入、计算、封装、返回、渲染”串起来,避免只记住零散语法。
怎么想:用户输入总秒数,程序自动换算成“时、分、秒”,并显示成 00:01:01 这种两位数形式。
怎么做:先弹窗输入总秒数,再封装 getTime 计算时分秒并补 0,最后把结果写到页面盒子中。
易错点:prompt 得到的是字符串,参与计算前要转成数字;页面展示要补 0,否则 1 不如 01 整齐。
三步拆解
为什么需要:案例虽小,但步骤不清就容易把“输入、计算、输出”混在一起。
怎么想:转写稿中明确分成三步:① 用户弹窗输入总秒数;② 封装 getTime,计算时分秒并补 0;③ 打印输出到页面。
怎么做:第一步用 let totalSeconds = +prompt('请您输入总的秒数:');第二步定义函数并调用;第三步用 document.write 输出盒子结构。
易错点:函数要先定义再调用;调用时小括号里写“实参”,定义时小括号里写“形参”。实参不一定是具体数字,也可以是变量,例如 getTime(totalSeconds)。
公式推导
为什么需要:总秒数不能直接拆成时分秒,需要按 60 进制换算。
怎么想:秒数对 60 取余,剩下的就是“秒”;总秒数除以 60 得到总分钟,再对 60 取余,就是“分钟”;总秒数除以 60 再除以 60 得到总小时,对 24 取余得到一天内的小时。
怎么做:
- 小时:
h = parseInt(t / 60 / 60 % 24) - 分钟:
m = parseInt(t / 60 % 60) - 秒数:
s = parseInt(t % 60)
易错点:parseInt是取整,不是“pasin”;取余符号是%,不是“余上”。例如输入 61 秒:61 % 60 = 1,所以秒是 1;parseInt(61 / 60 % 60) = 1,所以分钟是 1;小时是 0。调试时控制台输出0 1 1,说明公式正确。
函数封装与补零
为什么需要:计算逻辑要复用,且展示时间通常要求两位数。
怎么想:把总秒数作为形参 t 传进函数,先算出 h、m、s,再用三元表达式判断是否小于 10。
怎么做:
js
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s转写稿中验证:输入 61,补零前是 0 1 1,补零后控制台显示 00 01 01;输入 1000,可得到 0 16 40,即 16 分 40 秒。
易错点:补零后要重新赋值给 h/m/s,不能只写表达式;'0' 是字符串,拼接后变成字符串;函数内变量要写 let,否则直接赋值可能变成全局变量,很危险。变量查找遵循“先局部,局部没有再找全局”。
返回带标签字符串并渲染
为什么需要:计算结果不仅要打印,还要放进页面的三个 span 中。
怎么想:让 getTime 返回一段带标签的字符串,里面用模板字符串填入真实数据;外部用变量接住返回值,再塞进 .timer 盒子。
怎么做:函数中返回:
js
return `
<span class="hour">${h}</span>
<span class="minute">${m}</span>
<span class="second">${s}</span>
`调用 let str = getTime(totalSeconds),最后在 document.write 的模板字符串中把原来的三个 span 删掉,换成 \${str}。
易错点:return 返回的是“带标签的字符串”,不是数字;模板字符串要用反引号;\${str} 不要写成普通字符串拼接;页面输出时盒子外壳保留,三个 span 用返回值替换。
完整代码
html
<!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>综合案例-转换时间案例</title>
<style>
.box {
position: relative;
width: 190px;
height: 260px;
color: #fff;
background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
}
.title {
width: 100%;
text-align: center;
font-size: 30px;
font-weight: 700;
padding-top: 31px;
}
.count {
margin-top: 90px;
font-size: 14px;
text-align: center;
}
.timer {
margin-left: auto;
margin-right: auto;
width: 130px;
height: 30px;
margin-top: 10px;
display: block;
}
.timer span {
position: relative;
float: left;
width: 30px;
height: 30px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 20px;
}
.timer span:nth-child(-n+2)::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 18px;
width: 20px;
height: 100%;
top: 0;
}
.timer span:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<!-- <div class="box">
<div class="title">计算时间</div>
`<div>`
<div class="count">转换为时分秒</div>
<div class="timer">
<span class="hour">01</span>
<span class="minute">22</span>
<span class="second">58</span>
</div>
</div>
</div> -->
<script>
// 转换时分秒案例
// 计算公式:计算时分秒
// 小时: h = parseInt(总秒数 / 60 / 60 % 24)
// 分钟: m = parseInt(总秒数 / 60 % 60)
// 秒数: s = parseInt(总秒数 % 60)
// 1. 用户输入总的秒数
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
function getTime(t = 0) {
// 转换小时
let h = parseInt(t / 60 / 60 % 24)
// 转换分钟
let m = parseInt(t / 60 % 60)
// 转换秒数
let s = parseInt(t % 60)
// 数字补0
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
console.log(h, m, s)
return `
<span class="hour">\${h}</span>
<span class="minute">\${m}</span>
<span class="second">\${s}</span>
`
}
let str = getTime(totalSeconds) // 实参
console.log(str)
// 3. 页面打印输出
document.write(`
<div class="box">
<div class="title">计算时间</div>
`<div>`
<div class="count">转换为时分秒</div>
<div class="timer">
\${str}
</div>
</div>
</div>
`)
</script>
</body>
</html>课件图示








代码示例
代码一:综合案例完整代码(HTML + CSS + JS)
js
<!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>综合案例-转换时间案例</title>
<style>
.box {
position: relative;
width: 190px;
height: 260px;
color: #fff;
background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
}
.title {
width: 100%;
text-align: center;
font-size: 30px;
font-weight: 700;
padding-top: 31px;
}
.count {
margin-top: 90px;
font-size: 14px;
text-align: center;
}
.timer {
margin-left: auto;
margin-right: auto;
width: 130px;
height: 30px;
margin-top: 10px;
display: block;
}
.timer span {
position: relative;
float: left;
width: 30px;
height: 30px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 20px;
}
.timer span:nth-child(-n+2)::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 18px;
width: 20px;
height: 100%;
top: 0;
}
.timer span:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<script>
// 转换时分秒案例
// 计算公式:计算时分秒
// 小时: h = parseInt(总秒数 / 60 / 60 % 24)
// 分钟: m = parseInt(总秒数 / 60 % 60)
// 秒数: s = parseInt(总秒数 % 60)
// 1. 用户输入总的秒数
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
function getTime(t = 0) {
// 转换小时
let h = parseInt(t / 60 / 60 % 24)
// 转换分钟
let m = parseInt(t / 60 % 60)
// 转换秒数
let s = parseInt(t % 60)
// 数字补0
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
console.log(h, m, s)
return `
<span class="hour">${h}</span>
<span class="minute">${m}</span>
<span class="second">${s}</span>
`
}
let str = getTime(totalSeconds) // 实参
console.log(str)
// 3. 页面打印输出
document.write(`
<div class="box">
<div class="title">计算时间</div>
<div>
<div class="count">转换为时分秒</div>
<div class="timer">
${str}
</div>
</div>
</div>
`)
</script>
</body>
</html>关键行与易错点
let totalSeconds = +prompt('请您输入总的秒数:'):prompt拿到的是字符串,前面必须加+转成数字型,否则后面做除法会得到NaN。- 三个公式直接照抄:
h = parseInt(t / 60 / 60 % 24)、m = parseInt(t / 60 % 60)、s = parseInt(t % 60)。parseInt用来取整(时间是整数),% 24保证小时不超过 24。验证:61 秒 → 0 时 1 分 1 秒;1000 秒 → 16 分 40 秒。 - 补 0 写法:
h = h < 10 ? '0' + h : h。注意'0'必须加引号,写成0 + h就变成数字相加(0 + 1 = 1,得不到01);另外结果要重新赋值回h,只写表达式不赋值等于白做。 - 形参写成
t = 0是给默认值,防止调用时不传参变成undefined而算出NaN。 - 函数内
let h、let m、let s三个let一个都不能漏,漏了就成了隐式全局变量,后面很容易被覆盖。 return返回的是带标签的模板字符串(用反引号),里面用\${h}把算好的真实数据嵌进去。document.write里的.timer盒子不再写死三个 span,只用\${str}把函数返回的字符串塞进去即可,这是本案例最核心的思路。- 样式里的
url(./images/bg.png)需要本地有这张图,没有图片时代码照样能运行,只是背景色为纯红。
代码二:分步验证——先算时分秒,再做数字补 0
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分步验证-转换与补0</title>
</head>
<body>
<script>
// 1. 用户输入总的秒数(别忘了转数字型)
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime,把总的秒数转换为时分秒
function getTime(t = 0) {
// 转换小时
let h = parseInt(t / 60 / 60 % 24)
// 转换分钟
let m = parseInt(t / 60 % 60)
// 转换秒数
let s = parseInt(t % 60)
// 数字补0
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
console.log(h, m, s)
}
// 3. 调用函数,把变量当实参传进去
getTime(totalSeconds)
</script>
</body>
</html>关键行与易错点
- 这一步只做到"控制台验证",先确认计算和补 0 都对,再去渲染页面,排错会轻松很多。
- 调用
getTime(totalSeconds):小括号里是实参,实参不一定是写死的数字,放变量完全可以,变量里存的就是用户输入的秒数。 - 形参
t把实参接过来,后面所有公式里都用t参与计算,不要再写成别的变量名。 - 补 0 三行是最容易出错的地方:
'0' + h是字符串拼接,h必须是重新赋值,写成h < 10 ? '0' + h : h而不管它,打印出来还是0不是00。 - 输入 61,控制台应输出
00 01 01;输入 1000,应输出00 16 40。
代码三:函数 return 带标签的字符串,再渲染到页面
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>返回字符串并渲染</title>
</head>
<body>
<script>
// 1. 用户输入总的秒数
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime:计算 + 补0 + 返回带标签的字符串
function getTime(t = 0) {
let h = parseInt(t / 60 / 60 % 24)
let m = parseInt(t / 60 % 60)
let s = parseInt(t % 60)
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
return `
<span class="hour">${h}</span>
<span class="minute">${m}</span>
<span class="second">${s}</span>
`
}
// 3. 用变量接住返回值,再打印到页面
let str = getTime(totalSeconds)
console.log(str)
document.write(`
<div class="timer">
${str}
</div>
`)
</script>
</body>
</html>关键行与易错点
return后面返回的不是数字,而是一段带标签的字符串,模板字符串必须用反引号包裹,\${h}会被替换成真实数据。let str = getTime(totalSeconds):调用一次函数就执行一遍,并把return的结果装进str,此时str里已经是"三个带真实数据的 span"。document.write里的.timer只写外壳,用\${str}插入三个 span,所以原来素材里写死的01 / 22 / 58要删掉。- 常见坑:在模板字符串里写了
\${h}但h是函数内部的局部变量,函数外拿不到——必须先return出来再使用。 - 如果这段代码单独运行,因为没有引入代码一里的 CSS,
.timer span的方块样式不会出现,只是纯文本数字,但结构和数据是正确的;把<style>拷过来即可看到完整效果。
常见错误
1. 补零失效,输出 0 1 1 而不是 00 01 01
- 现象:小时/分钟/秒小于 10 时,前面没有出现 0。
- 原因:写成了
h = h < 10 ? 0 + h : h,0 + 5是数值加法得5,不是字符串拼接;或者写成h += '0'把零加在了后面。 - 修法:
'0'必须带引号且放在前面 ——h = h < 10 ? '0' + h : h,并且要把结果重新赋值回h。
2. 函数返回 undefined,页面 timer 里出现 undefined
- 现象:
let str = getTime(totalSeconds)后打印 str 是 undefined,页面渲染空白或报错。 - 原因:函数体内只写了
console.log(h, m, s)而没有return;或return写在模板字符串之前/之后位置不对,执行不到。 - 修法:把带三个 span 的模板字符串用
return返回,console.log只用于调试,不承担输出职责。
3. 输入 90000 秒,小时却显示 01
- 现象:秒数很大时小时数被"截断",看起来像丢数据。
- 原因:公式里的
% 24是取"一天内的第几小时",超过 24 小时的部分被主动丢弃。 - 修法:确认需求 —— 要"24 小时制显示"就保留
% 24;要显示累计小时数就去掉% 24,只写parseInt(t / 3600)。
4. 形参名和函数体里用的变量名不一致,结果全是 NaN / undefined
- 现象:
getTime(totalSeconds)调用正常,但函数里算出来的 h、m、s 都是 NaN。 - 原因:形参写的是
t,函数体里却继续写totalSeconds;此时函数内找不到该变量,会沿着作用域链去全局找,全局也没有就是undefined,参与运算即 NaN。 - 修法:形参名与函数体内引用的名字严格保持一致;这类错误不报错、只出错值,写完先
console.log(t)确认接到了。
5. 输入非数字或点"取消",页面显示 NaN:NaN:NaN
- 现象:prompt 直接取消或输入字母,三个 span 里全是 NaN。
- 原因:
+prompt(...)对null或非数字字符串转换结果是NaN,NaN参与任何算术运算仍是NaN,补零判断NaN < 10为 false 所以连 0 都不补。 - 修法:转换后先做校验,
if (isNaN(totalSeconds)) { ... }给出默认值或提示后终止,把非法输入挡在计算之前。
6. 页面样式全丢 / 结构错乱
- 现象:数字出来了,但没有红底黑块的效果,或三个方块挤在一起没有冒号。
- 原因:
document.write里拼的 HTML 少了.box或.timer外层容器;或 span 的 class 名拼错(hour/minute/second与 CSS 选择器不一致),CSS 里.timer span:nth-child(-n+2)::after的冒号依赖结构层级。 - 修法:渲染前把静态 HTML 结构和最终输出逐层比对,class 名一字不差;调试时可先只
document.write(str)看片段是否正确。
练习
练习 1(验证公式) 不写代码,先手算下列输入的结果并写出预期输出,再运行案例核对:61、3599、3600、86399、86400、90061。对不上的一项,指出是公式哪一部分造成的。
练习 2(改造需求) 把案例改成"累计时长"模式:输入 90000 秒应显示 25:00:00 而不是 01:00:00。只改一处代码实现,并说明改动后哪些输入的结果会与原来不同。
练习 3(拆分职责) 把 getTime 的返回值从 HTML 字符串改为数组 [h, m, s],由调用方负责拼三个 span 并 document.write。改造完成后对比两种写法:哪种更容易复用到"倒计时"场景?写出你的理由。
练习 4(复用扩展) 基于改造后的 getTime,做一个倒计时:输入总秒数后页面每秒刷新一次数字,减到 00:00:00 自动停止(提示:setInterval + 一个外部变量保存剩余秒数 + clearInterval)。要求倒计时过程中数字始终补零。
练习 5(健壮性) 为案例加上输入防护:用户取消 prompt、输入空字符串、输入负数、输入 abc 时,页面都应正常渲染 00:00:00 并给出提示,而不是出现 NaN 或报错。写出你的判断逻辑,并列出你测试过的边界用例清单。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 综合案例-转换时分秒上 | 10:48 |
| 2 | 综合案例-转换时分秒下 | 07:09 |
小结
- 这个案例真正的难点不在换算公式,而在"数据 → 字符串 → 页面"这条链路的职责划分:函数只负责算和拼,调用方只负责接住和放入容器。
- 实参可以是变量而非字面量;形参一旦命名,函数体内必须使用同一个名字 —— 名字不一致不会报错,只会静默地拿到
undefined并污染全部计算结果。 - 补零的本质是三目运算加字符串拼接,
'0'带不带引号决定了是"补零"还是"加零",这是本案例最高频的一处翻车点。 return决定了函数的产出形态;返回"带标签的字符串"是模板渲染的最小雏形,后续组件化、列表渲染都是这个思路的放大版。- 函数内变量必须
let声明,漏写会变成隐式全局变量,函数调用两次以上就可能互相污染 —— 这类 bug 在单次运行时完全看不出来。 - 边界输入(0、负数、null、非数字、超过 24 小时、正好 86400)是换算类需求的第一批测试用例,应在写代码前就想清楚期望行为,而不是等页面出 NaN 再补判断。
- 调试节奏上,"先验证 h/m/s → 再验证返回字符串 → 最后验证页面渲染"的分段验证,比一次性写完再看效果要快得多。