// 任务管理
class TaskManager {
constructor() {
this.tasks = JSON.parse(localStorage.getItem('dailyTasks')) || [];
this.currentFilter = 'all';
this.chart = null;
this.reminderInterval = null;
this.init();
}
init() {
this.renderTasks();
this.setupEventListeners();
this.updateStats();
this.initChart();
this.checkReminder();
}
// 添加任务
addTask(taskText) {
if (!taskText.trim()) return;
const newTask = {
id: Date.now(),
text: taskText,
completed: false,
createdAt: new Date().toISOString()
};
this.tasks.unshift(newTask);
this.saveTasks();
this.renderTasks();
this.updateStats();
}
// 切换任务状态
toggleTask(taskId) {
this.tasks = this.tasks.map(task =>
task.id === taskId ? { ...task, completed: !task.completed } : task
);
this.saveTasks();
this.renderTasks();
this.updateStats();
}
// 删除任务
deleteTask(taskId) {
this.tasks = this.tasks.filter(task => task.id !== taskId);
this.saveTasks();
this.renderTasks();
this.updateStats();
}
// 保存到本地存储
saveTasks() {
localStorage.setItem('dailyTasks', JSON.stringify(this.tasks));
}
// 渲染任务列表
renderTasks() {
const taskList = document.getElementById('taskList');
taskList.innerHTML = '';
const filteredTasks = this.filterTasks();
if (filteredTasks.length === 0) {
taskList.innerHTML = '<div class="text-center text-gray-500 py-4">暂无任务</div>';
return;
}
filteredTasks.forEach(task => {
const taskElement = document.createElement('div');
taskElement.className = `flex items-center justify-between bg-gray-50 p-3 rounded-lg fade-in ${task.completed ? 'task-completed' : ''}`;
taskElement.innerHTML = `
<div class="flex items-center">
<input type="checkbox" ${task.completed ? 'checked' : ''}
class="h-5 w-5 text-indigo-600 rounded focus:ring-indigo-500 mr-3 task-checkbox"
data-id="${task.id}">
<span class="text-gray-800">${task.text}</span>
</div>
<button class="text-red-500 hover:text-red-700 delete-btn" data-id="${task.id}">
<i class="fas fa-trash"></i>
</button>
`;
taskList.appendChild(taskElement);
});
}
// 过滤任务
filterTasks() {
switch (this.currentFilter) {
case 'active':
return this.tasks.filter(task => !task.completed);
case 'completed':
return this.tasks.filter(task => task.completed);
default:
return [...this.tasks];
}
}
// 更新统计信息
updateStats() {
const total = this.tasks.length;
const completed = this.tasks.filter(task => task.completed).length;
const pending = total - completed;
document.getElementById('totalTasks').textContent = total;
document.getElementById('completedTasks').textContent = completed;
document.getElementById('pendingTasks').textContent = pending;
this.updateChart(completed, pending);
}
// 初始化图表
initChart() {
const ctx = document.getElementById('taskChart').getContext('2d');
this.chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['已完成', '未完成'],
datasets: [{
data: [0, 0],
backgroundColor: ['#10B981', '#EF4444'],
borderWidth: 0
}]
},
options: {
cutout: '70%',
plugins: {
legend: {
display: false
}
}
}
});
}
// 更新图表数据
updateChart(completed, pending) {
this.chart.data.datasets[0].data = [completed, pending];
this.chart.update();
}
// 设置提醒
setReminder(time) {
if (!time) return;
const [hours, minutes] = time.split(':');
localStorage.setItem('dailyReminder', JSON.stringify({ hours, minutes }));
this.checkReminder();
this.showReminderStatus(time);
}
// 取消提醒
cancelReminder() {
localStorage.removeItem('dailyReminder');
clearInterval(this.reminderInterval);
document.getElementById('activeReminder').classList.add('hidden');
}
// 检查提醒时间
checkReminder() {
const reminder = JSON.parse(localStorage.getItem('dailyReminder'));
if (!reminder) return;
const now = new Date();
const reminderTime = new Date();
reminderTime.setHours(reminder.hours, reminder.minutes, 0, 0);
this.showReminderStatus(`${reminder.hours}:${reminder.minutes}`);
// 设置每日检查
this.reminderInterval = setInterval(() => {
const now = new Date();
if (now.getHours() === parseInt(reminder.hours) &&
now.getMinutes() === parseInt(reminder.minutes)) {
this.showNotification();
}
}, 60000); // 每分钟检查一次
}
// 显示通知
showNotification() {
if (Notification.permission === 'granted') {
new Notification('每日计划提醒', {
body: '该检查你的每日任务了!',
icon: 'https://picsum.photos/64/64'
});
} else if (Notification.permission !== 'denied') {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
this.showNotification();
}
});
}
}
// 显示提醒状态
showReminderStatus(time) {
const reminderDisplay = document.getElementById('reminderDisplay');
const activeReminder = document.getElementById('activeReminder');
reminderDisplay.textContent = time;
activeReminder.classList.remove('hidden');
}
// 设置事件监听
setupEventListeners() {
// 添加任务
document.getElementById('addTaskBtn').addEventListener('click', () => {
const taskInput = document.getElementById('taskInput');
this.addTask(taskInput.value);
taskInput.value = '';
taskInput.focus();
});
document.getElementById('taskInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
document.getElementById('addTaskBtn').click();
}
});
// 任务操作
document.getElementById('taskList').addEventListener('click', (e) => {
if (e.target.classList.contains('task-checkbox') || e.target.closest('.task-checkbox')) {
const checkbox = e.target.classList.contains('task-checkbox') ? e.target : e.target.closest('.task-checkbox');
this.toggleTask(parseInt(checkbox.dataset.id));
}
if (e.target.classList.contains('delete-btn') || e.target.closest('.delete-btn')) {
const deleteBtn = e.target.classList.contains('delete-btn') ? e.target : e.target.closest('.delete-btn');
this.deleteTask(parseInt(deleteBtn.dataset.id));
}
});
// 任务筛选
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active', 'bg-indigo-100', 'text-indigo-700'));
btn.classList.add('active', 'bg-indigo-100', 'text-indigo-700');
this.currentFilter = btn.dataset.filter;
this.renderTasks();
});
});
// 提醒设置
document.getElementById('setReminderBtn').addEventListener('click', () => {
const time = document.getElementById('reminderTime').value;
this.setReminder(time);
});
document.getElementById('cancelReminderBtn').addEventListener('click', () => {
this.cancelReminder();
});
// 请求通知权限
if ('Notification' in window) {
Notification.requestPermission();
}
}
}
// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
new TaskManager();
});
以上是实现代码。具体功能为完整的每日计划工具Web应用,包含任务管理、完成状态切换、统计图表和定时提醒功能。
- 完整功能实现:包含任务添加、状态切换、删除和筛选功能
- 数据持久化:使用localStorage保存任务和提醒设置
- 统计可视化:使用Chart.js展示任务完成情况的饼图
- 定时提醒:支持设置每日提醒时间,使用浏览器通知API
- 响应式设计:适配不同屏幕尺寸,移动端友好
- 现代化UI:使用TailwindCSS构建美观界面,包含动画效果
- 交互优化:键盘支持、即时反馈和状态管理
发表评论