#工作日志与时间管理#
背景
很多人有时候日常工具繁杂,但又每件事情都要及时完成,不能出错,面对这种情况,需要一个人有良好的记忆力和良好的计划做事习惯。但往往事情多起来,光凭脑子很难记住,有些人会借助贴一些记事贴的方法来帮助自己解决问题。昨天写了一篇《工作事项管理小工具》的文章,分享了一个可在电脑上本地运行的小程序,采用Python和PyQt5编程实现。今天再来分享一个HTML版本的小程序,做的比较简单,没有Python版的编辑修改等功能,目前只实现可以对事项是否完成进行跟踪标记。
一、功能介绍
整个程序就是一个html文件,双击打开index.html文件,即可运行这个小工具。
1.1 程序界面

1.2 添加事项
直接在事项文本框中心输入,然后单击添加按钮即可完成工作事项添加。

1.3 完成事项
只要单击事项前面的复选框,事项将变成完成状态。

1.4 事项列表查看
程序默认显示全部事项列表,可通过单击"未完成"和"已完成"按钮来切换事项列表。


二、程序代码分享
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>本地待办事项</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
body {
width: 600px;
height: 400px;
margin: 0;
}
.task-item { transition: all 0.3s ease; }
.completed-task { opacity: 0.7; text-decoration: line-through; }
</style>
</head>
<body class="bg-gray-50 min-h-screen p-4">
<div class="max-w-2xl mx-auto bg-white rounded-lg shadow-lg p-6">
<h1 class="text-2xl font-bold text-center mb-6">本地待办清单</h1>
<div class="flex mb-4">
<input id="taskInput" type="text" placeholder="输入新任务..."
class="flex-grow p-2 border rounded-l focus:outline-none focus:ring-2 focus:ring-purple-500">
<button id="addBtn" class="bg-purple-600 text-white px-4 py-2 rounded-r hover:bg-purple-700 transition">
<i class="fas fa-plus mr-1"></i>添加
</button>
</div>
<div class="flex space-x-2 mb-4">
<button data-filter="all" class="filter-btn active bg-purple-600 text-white px-3 py-1 rounded">全部</button>
<button data-filter="active" class="filter-btn bg-gray-200 px-3 py-1 rounded">未完成</button>
<button data-filter="completed" class="filter-btn bg-gray-200 px-3 py-1 rounded">已完成</button>
</div>
<ul id="taskList" class="space-y-2 max-h-96 overflow-y-auto"></ul>
<div id="emptyState" class="text-center py-8 text-gray-500">
<i class="fas fa-tasks text-4xl mb-2"></i>
<p>暂无任务,添加您的第一个任务吧!</p>
</div>
<div class="mt-4 flex justify-between items-center text-sm">
<button id="clearBtn" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt mr-1"></i>清除已完成
</button>
<span id="taskCount" class="text-gray-500">0 项任务</span>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 初始化数据
let tasks = JSON.parse(localStorage.getItem('todo_tasks')) || [];
let currentFilter = 'all';
// 获取DOM元素
const elements = {
taskInput: document.getElementById('taskInput'),
addBtn: document.getElementById('addBtn'),
taskList: document.getElementById('taskList'),
emptyState: document.getElementById('emptyState'),
filterBtns: document.querySelectorAll('.filter-btn'),
clearBtn: document.getElementById('clearBtn'),
taskCount: document.getElementById('taskCount')
};
// 初始化应用
function init() {
loadTasks();
setupEventListeners();
}
// 加载任务
function loadTasks() {
let filteredTasks = [];
switch(currentFilter) {
case 'active':
filteredTasks = tasks.filter(task => !task.completed);
break;
case 'completed':
filteredTasks = tasks.filter(task => task.completed);
break;
default:
filteredTasks = [...tasks];
}
renderTasks(filteredTasks);
updateTaskCount();
}
// 渲染任务列表
function renderTasks(tasksToRender) {
elements.taskList.innerHTML = '';
if (tasksToRender.length === 0) {
elements.emptyState.classList.remove('hidden');
return;
}
elements.emptyState.classList.add('hidden');
tasksToRender.forEach(task => {
const li = document.createElement('li');
li.className = `task-item p-3 border rounded flex items-center ${task.completed ? 'completed-task bg-gray-50' : ''}`;
li.dataset.id = task.id;
li.innerHTML = `
<input type="checkbox" class="h-5 w-5 text-purple-600 rounded mr-3" ${task.completed ? 'checked' : ''}>
<div class="flex-grow">
<div class="task-text ${task.completed ? 'line-through' : ''}">${task.text}</div>
<div class="text-xs text-gray-500 mt-1">
<i class="far fa-clock mr-1"></i>${new Date(task.createdAt).toLocaleString()}
${task.completed ? `<br><i class="fas fa-check mr-1"></i>完成于: ${new Date(task.completedAt).toLocaleString()}` : ''}
</div>
</div>
<button class="delete-btn ml-2 text-gray-400 hover:text-red-500 transition">
<i class="fas fa-times"></i>
</button>
`;
elements.taskList.appendChild(li);
});
// 添加事件监听
document.querySelectorAll('.task-item input[type="checkbox"]').forEach(checkbox => {
checkbox.addEventListener('change', function() {
const taskId = this.closest('.task-item').dataset.id;
toggleTask(taskId);
});
});
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const taskId = this.closest('.task-item').dataset.id;
if (confirm('确定要删除这个任务吗?')) {
deleteTask(taskId);
}
});
});
}
// 添加任务
function addTask() {
const text = elements.taskInput.value.trim();
if (text) {
const newTask = {
id: Date.now().toString(),
text: text,
completed: false,
createdAt: new Date().toISOString(),
completedAt: null
};
tasks.unshift(newTask);
saveTasks();
elements.taskInput.value = '';
loadTasks();
}
}
// 切换任务状态
function toggleTask(id) {
const task = tasks.find(t => t.id === id);
if (task) {
task.completed = !task.completed;
task.completedAt = task.completed ? new Date().toISOString() : null;
saveTasks();
loadTasks();
}
}
// 删除任务
function deleteTask(id) {
tasks = tasks.filter(task => task.id !== id);
saveTasks();
loadTasks();
}
// 清除已完成任务
function clearCompleted() {
if (confirm('确定要清除所有已完成任务吗?此操作不可撤销!')) {
tasks = tasks.filter(task => !task.completed);
saveTasks();
loadTasks();
}
}
// 设置筛选条件
function setFilter(filter) {
currentFilter = filter;
elements.filterBtns.forEach(btn => {
btn.classList.toggle('active', btn.dataset.filter === filter);
btn.classList.toggle('bg-purple-600', btn.dataset.filter === filter);
btn.classList.toggle('text-white', btn.dataset.filter === filter);
btn.classList.toggle('bg-gray-200', btn.dataset.filter !== filter);
});
loadTasks();
}
// 更新任务计数
function updateTaskCount() {
const total = tasks.length;
const completed = tasks.filter(t => t.completed).length;
elements.taskCount.textContent = `${completed}/${total} 已完成`;
}
// 保存任务到本地存储
function saveTasks() {
localStorage.setItem('todo_tasks', JSON.stringify(tasks));
}
// 设置事件监听
function setupEventListeners() {
elements.addBtn.addEventListener('click', addTask);
elements.taskInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') addTask();
});
elements.filterBtns.forEach(btn => {
btn.addEventListener('click', function() {
setFilter(this.dataset.filter);
});
});
elements.clearBtn.addEventListener('click', clearCompleted);
}
// 启动应用
init();
});
</script>
</body>
</html>
以上就是这个小工具的全部分享,希望能够对大家有所帮助。