待办事项清单专案:用HTML、CSS和Flask建构的简易任务管理工具

简介

在快节奏的生活中,保持高效和组织性是非常重要的。待办事项清单(To-do List)应用程序是一种实用的工具,可以帮助我们管理任务、设置截止日期并跟踪进度。本文将介绍如何使用 HTML、CSS 和 JavaScript 创建一个简单的待办事项清单应用程序,并实现任务的新增、删除、标记完成和排序功能。

功能介绍

我们的待办事项清单应用程序具备以下功能:

  1. 新增任务:用户可以输入任务名称和截止日期,并将任务添加到清单中。
  2. 删除任务:用户可以删除已添加的任务。
  3. 标记完成:用户可以将任务标记为已完成,并在清单中进行标记。

index.html
<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>待辦事項清單</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="app">
        <div id="sidebar">
            <h1>新增任務</h1>
            <input type="text" id="task-input" placeholder="新增任務..." required>
            <input type="date" id="task-deadline" placeholder="截止日期">
            <button id="add-task-btn">新增任務</button>
        </div>
        <div id="task-container">
            <h2>待辦事項</h2>
            <ul id="task-list"></ul>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>
styles.css
body {
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    height: 100vh; /* 使內容填滿整個視窗 */
    background-color: #f9f9f9; /* 背景顏色 */
}

#app {
    display: flex;
    width: 100%;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 整體框架陰影 */
}

#sidebar {
    width: 300px; /* 左側新增任務區域的寬度 */
    padding: 20px;
    background-color: #ffffff; /* 左側背景色 */
    border-right: 1px solid #ddd; /* 右側邊界 */
    overflow-y: auto; /* 支持垂直滾動 */
}

#task-container {
    flex-grow: 1; /* 右側自動擴展 */
    padding: 20px;
    background-color: #ffffff; /* 右側背景色 */
    overflow-y: auto; /* 支持垂直滾動 */
}

h1, h2 {
    margin: 0 0 15px 0;
    color: #333; /* 標題顏色 */
}

input[type="text"], input[type="date"] {
    width: 90%; /* 使輸入框和按鈕填滿寬度 */
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid #ccc; /* 輸入框邊界顏色 */
    border-radius: 4px; /* 圓角邊框 */
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* 輸入框陰影 */
}

#add-task-btn {
    background-color: #66afe9; /* 按鈕背景顏色 */
    color: white; /* 按鈕文字顏色 */
    border: none; /* 取消按鈕邊框 */
    border-radius: 4px; /* 按鈕圓角 */
    cursor: pointer; /* 滑鼠指標 */
    transition: background-color 0.3s; /* 背景顏色過渡效果 */
    padding: 10px; /* 按鈕內部間距 */
}

#add-task-btn:hover {
    background-color: #5a9bcf; /* 滑鼠懸停時按鈕顏色 */
}

ul {
    list-style-type: none; /* 去掉項目符號 */
    padding: 0;
}

li {
    padding: 10px;
    border: 1px solid #ddd;
    margin-bottom: 10px;
    display: flex;  /* 使用 Flexbox 來排列內容 */
    justify-content: space-between; /* 讓內容和按鈕兩端對齊 */
    align-items: center; /* 垂直置中 */
    border-radius: 4px; /* 列表項圓角 */
    background-color: #f9f9f9; /* 列表項背景色 */
    transition: background-color 0.3s; /* 背景顏色過渡效果 */
}

li:hover {
    background-color: #f1f1f1; /* 懸停時背景顏色 */
}

/* 已完成任務的樣式 */
.completed {
    text-decoration: line-through; /* 標記為完成的任務加上刪除線 */
    color: gray; /* 完成的任務顯示為灰色 */
    background-color: #e0f7fa; /* 完成任務的底色 */
    border: 1px solid #b2ebf2; /* 完成任務的邊框顏色 */
}

/* 完成按鈕和刪除按鈕的樣式 */
.complete-btn, .delete-btn {
    background-color: #4caf50; /* 完成按鈕的背景色 */
    color: white; /* 完成按鈕的文字顏色 */
    border: none; /* 取消按鈕邊框 */
    border-radius: 4px; /* 按鈕圓角 */
    cursor: pointer; /* 滑鼠指標 */
    padding: 5px 10px; /* 按鈕內部間距 */
    transition: background-color 0.3s; /* 背景顏色過渡效果 */
    margin-left: 5px; /* 按鈕之間的間隔 */
}

.complete-btn:hover {
    background-color: #45a049; /* 滑鼠懸停時完成按鈕顏色 */
}

.delete-btn {
    background-color: #f44336; /* 刪除按鈕的背景色 */
}

.delete-btn:hover {
    background-color: #d32f2f; /* 滑鼠懸停時刪除按鈕顏色 */
}
 script.js
const taskInput = document.getElementById('task-input');
const taskDeadline = document.getElementById('task-deadline');
const addTaskBtn = document.getElementById('add-task-btn');
const taskList = document.getElementById('task-list');

// 新增任務的事件監聽器
addTaskBtn.addEventListener('click', () => {
    const taskText = taskInput.value;
    const deadline = taskDeadline.value;

    if (taskText) {
        const taskItem = document.createElement('li');
        taskItem.textContent = `${taskText} (截止: ${deadline})`;
        
        // 完成按鈕
        const completeBtn = document.createElement('button');
        completeBtn.textContent = '標記為完成';
        completeBtn.classList.add('complete-btn');

        completeBtn.addEventListener('click', () => {
            taskItem.classList.toggle('completed');
            completeBtn.textContent = taskItem.classList.contains('completed') ? '標記為未完成' : '標記為完成';
        });

        // 刪除按鈕
        const deleteBtn = document.createElement('button');
        deleteBtn.textContent = '刪除';
        deleteBtn.classList.add('delete-btn');

        deleteBtn.addEventListener('click', () => {
            taskItem.remove();
        });

        taskItem.appendChild(completeBtn);
        taskItem.appendChild(deleteBtn);
        taskList.appendChild(taskItem);

        // 清空輸入框
        taskInput.value = '';
        taskDeadline.value = '';
    }
});
app.py
from flask import Flask, request, jsonify, send_from_directory
from datetime import datetime
import json
import os

app = Flask(__name__)
tasks = []  # 假设的任务数据
task_id = 1  # 任务ID计数器
tasks_file = 'tasks.json'  # 任务数据文件

# 读取任务数据
def load_tasks():
    global task_id
    if os.path.exists(tasks_file):
        with open(tasks_file, 'r', encoding='utf-8') as f:
            global tasks
            tasks = json.load(f)
            # 设置任务 ID
            if tasks:
                task_id = max(task['id'] for task in tasks) + 1

# 保存任务数据
def save_tasks():
    with open(tasks_file, 'w', encoding='utf-8') as f:
        json.dump(tasks, f, ensure_ascii=False, indent=4)

# 静态文件
@app.route('/public/<path:path>')
def send_public(path):
    return send_from_directory('public', path)

# 处理GET请求,返回任务列表
@app.route('/tasks', methods=['GET'])
def get_tasks():
    return jsonify(tasks)

# 处理POST请求,新增任务
@app.route('/tasks', methods=['POST'])
def add_task():
    global task_id
    task_data = request.json
    task_data['id'] = task_id
    task_data['created_at'] = datetime.now().isoformat()  # 记录新增时间
    tasks.append(task_data)
    save_tasks()  # 保存任务数据
    task_id += 1
    return jsonify(task_data), 201

# 处理PATCH请求,标记任务为完成或未完成
@app.route('/tasks/<int:task_id>', methods=['PATCH'])
def toggle_task(task_id):
    for task in tasks:
        if task['id'] == task_id:
            task['completed'] = not task.get('completed', False)
            save_tasks()  # 保存任务数据
            return jsonify(task), 200
    return jsonify({'error': '任务不存在'}), 404

# 处理DELETE请求,删除任务
@app.route('/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    global tasks
    tasks = [task for task in tasks if task['id'] != task_id]  # 删除指定的任务
    save_tasks()  # 保存任务数据
    return jsonify({'message': '任务已删除'}), 204  # 返回204状态码表示成功删除

# 启动服务器
if __name__ == '__main__':
    load_tasks()  # 加载任务数据
    app.run(port=8000)

结语

通过以上代码,我们实现了一个简单而功能完善的待办事项清单应用程序。你可以根据自己的需求进一步扩展此应用,添加更多功能,比如用户认证、任务分类等。希望这篇文章能够帮助你创建自己的任务管理工具,提升生活的组织性和效率!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值