💰 基于 HTML+CSS+JavaScript 的薪资实时计算器(含本地存储和炫酷动画)
1. 前言
在日常工作中,我们经常会关心自己每天、甚至每分钟赚了多少钱。
于是我用 原生 HTML + CSS + JavaScript 实现了一个 薪资实时计算器:
- 📅 输入本月薪资 & 工作天数 → 自动计算日薪
- 🕒 输入上下班时间 → 根据当前时间实时计算当日已赚金额
- 💾 支持本地存储(刷新仍可保持数据)
- ✨ 动态动画效果(数字变化 & 进度条)
- 📱 响应式设计,PC / 手机均可使用
它不仅是一款小工具,也能让学习前端的同学练习 DOM 操作 、时间计算 、localStorage 以及 UI 动效 的综合能力。
2. 实现思路
📝 我们可以将这个功能拆解为 4 个核心模块:
-
数据输入与保存
- 用户输入:月薪、工作天数、上班时间、下班时间
- 使用
localStorage
持久化存储
-
日薪计算公式
日薪=月薪工作天数 \text{日薪} = \frac{\text{月薪}}{\text{工作天数}} 日薪=工作天数月薪 -
实时薪资计算公式
- 获取当前时间
now
- 计算上下班时间差
totalTime
- 计算已工作时间
elapsed
- 计算已赚金额:
实时薪资=elapsedtotalTime×日薪 \text{实时薪资} = \frac{elapsed}{totalTime} \times \text{日薪} 实时薪资=totalTimeelapsed×日薪
- 获取当前时间
-
UI 展示与动态更新
- 使用
setInterval
每秒更新计算 - 数字渐变效果
- 进度条展示已完成工作进度
- 使用
3. 页面效果展示
我们先来看看完整效果(PC + 移动端均可运行):
特点:
- 🌈 玻璃拟态风格(半透明背景 + 模糊)
- 📊 进度条动画(已工作时间比例)
- ⏱ 实时更新数字(每秒跳动)
- 💾 刷新不丢数据
4. 核心代码
下面是完整的 index.html
(可直接运行):
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>薪资实时计算器</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #232526, #414345);
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background: rgba(255, 255, 255, 0.08);
padding: 25px;
border-radius: 15px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.37);
backdrop-filter: blur(12px);
width: 350px;
}
h2 {
text-align: center;
margin-bottom: 15px;
}
label {
display: block;
margin-top: 10px;
font-size: 14px;
color: #ccc;
}
input {
width: 100%;
padding: 8px;
margin-top: 5px;
border: none;
outline: none;
border-radius: 5px;
background: rgba(255, 255, 255, 0.15);
color: #fff;
}
button {
margin-top: 15px;
width: 100%;
padding: 10px;
border: none;
border-radius: 5px;
background: linear-gradient(90deg, #ff7eb3, #ff758c);
color: white;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s;
}
button:hover {
transform: scale(1.05);
}
.result {
margin-top: 20px;
font-size: 18px;
text-align: center;
}
.salary-number {
font-size: 32px;
font-weight: bold;
color: #ffde59;
text-shadow: 0 0 10px #ffde59;
transition: all 0.3s ease;
}
.progress-bar {
margin-top: 10px;
height: 8px;
background: rgba(255,255,255,0.2);
border-radius: 5px;
overflow: hidden;
}
.progress {
height: 100%;
background: linear-gradient(90deg, #ff758c, #ff7eb3);
transition: width 0.5s ease;
}
</style>
</head>
<body>
<div class="container">
<h2>💰 薪资实时计算器</h2>
<label>当月薪资(¥)</label>
<input type="number" id="salary" placeholder="输入当月薪资">
<label>当月工作天数</label>
<input type="number" id="workDays" placeholder="输入工作天数">
<label>上班时间(HH:MM)</label>
<input type="time" id="startTime">
<label>下班时间(HH:MM)</label>
<input type="time" id="endTime">
<button id="saveBtn">保存设置</button>
<div class="result">
<div>日薪:<span id="dailySalary" class="salary-number">0</span> 元</div>
<div>今日实时薪资:</div>
<div id="realTimeSalary" class="salary-number">0</div>
<div class="progress-bar">
<div id="progress" class="progress" style="width:0%"></div>
</div>
</div>
</div>
<script>
const salaryInput = document.getElementById("salary");
const workDaysInput = document.getElementById("workDays");
const startInput = document.getElementById("startTime");
const endInput = document.getElementById("endTime");
const dailySalaryEl = document.getElementById("dailySalary");
const realTimeSalaryEl = document.getElementById("realTimeSalary");
const progressEl = document.getElementById("progress");
function loadSettings() {
const settings = JSON.parse(localStorage.getItem("salarySettings"));
if (settings) {
salaryInput.value = settings.salary;
workDaysInput.value = settings.workDays;
startInput.value = settings.startTime;
endInput.value = settings.endTime;
}
}
function saveSettings() {
const settings = {
salary: Number(salaryInput.value),
workDays: Number(workDaysInput.value),
startTime: startInput.value,
endTime: endInput.value
};
localStorage.setItem("salarySettings", JSON.stringify(settings));
calculateDailySalary();
}
function calculateDailySalary() {
const salary = Number(salaryInput.value);
const workDays = Number(workDaysInput.value);
if (salary > 0 && workDays > 0) {
const daily = salary / workDays;
dailySalaryEl.textContent = daily.toFixed(2);
}
}
function calculateRealTimeSalary() {
const settings = JSON.parse(localStorage.getItem("salarySettings"));
if (!settings) return;
const { salary, workDays, startTime, endTime } = settings;
if (!salary || !workDays || !startTime || !endTime) return;
const daily = salary / workDays;
const now = new Date();
const [sh, sm] = startTime.split(":").map(Number);
const [eh, em] = endTime.split(":").map(Number);
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), sh, sm);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), eh, em);
const totalTime = end - start;
const elapsed = Math.max(0, Math.min(now - start, totalTime));
const progress = (elapsed / totalTime) * 100;
progressEl.style.width = progress + "%";
let earned = (elapsed / totalTime) * daily;
if (earned < 0) earned = 0;
if (earned > daily) earned = daily;
realTimeSalaryEl.textContent = earned.toFixed(2);
}
document.getElementById("saveBtn").addEventListener("click", saveSettings);
loadSettings();
calculateDailySalary();
setInterval(() => {
calculateDailySalary();
calculateRealTimeSalary();
}, 1000);
</script>
</body>
</html>
5. 技术要点
5.1 时间计算
- 使用
Date
对象计算上下班总工时和已工作时长。 Math.min
&Math.max
确保数据不会越界(下班后不继续涨薪)。
5.2 动态进度条
- 进度条宽度 =
elapsed / totalTime * 100%
- CSS
transition
实现平滑动画。
5.3 本地存储
localStorage.setItem(key, value)
保存数据localStorage.getItem(key)
读取数据- 用
JSON.stringify
/JSON.parse
存取对象
5.4 UI 亮点
- 玻璃拟态(
backdrop-filter: blur()
) - 渐变背景(
linear-gradient
) - 阴影与高光效果
6. 可扩展优化方向
💡 未来可以优化:
- 数字滚动动画(像余额实时跳动效果)
- PWA 支持(可安装到手机桌面使用)
- 夜间/日间主题切换
- 多币种汇率换算
7. 总结
通过本项目你可以学到:
- HTML 表单数据获取
- JavaScript 时间差计算
- 进度条动画
- localStorage 数据持久化
- 响应式 & 美化设计
这是一个非常适合前端初中级学习者的综合练习项目。