day49-Todo List(待办事项列表)

50 天学习 50 个项目 - HTMLCSS and JavaScript

day49-Todo List(待办事项列表)

效果

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Todo List</title>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <h1>todos</h1>
    <form id="form">
        <!-- 输入 -->
        <!--autocomplete="off" 用于控制浏览器是否自动填充输入字段的功能。它主要用于阻止浏览器在用户输入时自动弹出先前输入过的值或历史记录。 -->
        <!-- 由于会多次输入,所以添加autocomplete="off" 以提高用户体验 -->
        <input type="text" class="input" id="input" placeholder="Enter your todo" autocomplete="off">
        <!-- 显示todo list -->
        <ul class="todos" id="todos"></ul>
    </form>
    <small>左键单击以切换完成。<br> 右键单击可删除待办事项</small>

    <script src="script.js"></script>
</body>

</html>

style.css

css 复制代码
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background-color: #f5f5f5;
    color: #444;
    font-family: 'Poppins', sans-serif;
    /* 子元素竖直居中 */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
}

/* 标题 */
h1 {
    color: aqua;
    font-size: 10rem;
    text-align: center;
    opacity: 0.5;
}

/* 带有input的form表单 */
form {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.8),
        4px 0px 10px rgba(255, 255, 255, 0.9);
    max-width: 100%;
    width: 400px;
}

/* 输入框 */
.input {
    border: none;
    color: #444;
    font-size: 2rem;
    padding: 1rem 2rem;
    display: block;
    width: 100%;
}

.input::placeholder {
    color: #d5d5d5;
}

.input:focus {
    outline-color: aqua;
}

/* 显示区域 */
.todos {
    background-color: #fff;
    list-style-type: none;
}

/* 每一项 */
.todos li {
    border-top: 1px solid #e5e5e5;
    cursor: pointer;
    font-size: 1.5rem;
    padding: 1rem 2rem;
}

/* 完成后,添加删除线 */
.todos li.completed {
    color: #b6b6b6;
    text-decoration: line-through;
}

/* 提示文本 */
small {
    color: #b5b5b5;
    margin-top: 1rem;
    text-align: center;
}

script.js

javascript 复制代码
// 重点 flex text-decoration: line-through; localStorage JSON
// 1.获取元素节点
const form = document.getElementById('form')//表单
const input = document.getElementById('input')//输入框
const todosUL = document.getElementById('todos')//todos容器
// 获取本地存储的todolist
const todos = JSON.parse(localStorage.getItem('todos'))
// 如果有,则遍历,显示
if (todos) {
    todos.forEach(todo => addTodo(todo))
}
// 表单提交 即输入框回车后
form.addEventListener('submit', (e) => {
    // 阻止表单默认行为 不希望发生页面刷新或导航行为
    e.preventDefault()
    // 添加todo
    addTodo()
})
// 函数 添加todo
function addTodo(todo) {
    // 获取input的值
    let todoText = input.value
    // 如果todo存在值,即本地存储时有值,比如10行代码执行时
    if (todo) {
        todoText = todo.text
    }
    // 值存在,防止表单提交后,但是在表单的input并未输入值
    if (todoText) {
        // 创建li
        const todoEl = document.createElement('li')
        // 本地存储,并且时完成的,则添加删除线
        if (todo && todo.completed) {
            todoEl.classList.add('completed')
        }
        // 文本
        todoEl.innerText = todoText
        // 单机,即左键 完成
        todoEl.addEventListener('click', () => {
            todoEl.classList.toggle('completed')
            // 更新本地存储
            updateLS()
        })
        // 右键
        todoEl.addEventListener('contextmenu', (e) => {
            // 阻止右键的默认行为,即跳出菜单
            e.preventDefault()
            // 移除dom节点
            todoEl.remove()
            // 更新本地存储
            updateLS()
        })
        // 添加到ul中的第一个位置
        todosUL.insertBefore(todoEl, todosUL.children[0])
        // 置空input
        input.value = ''
        // 更新本地存储
        updateLS()
    }
}
// 函数:更新本地存储
function updateLS() {
    // 获取所有的todo
    let todosEl = document.querySelectorAll('li')
    // 先设置空的
    const todos = []
    // 再遍历添加每一项
    todosEl.forEach(todoEl => {
        todos.push({
            text: todoEl.innerText,//文本
            completed: todoEl.classList.contains('completed')//是否完成
        })
    })
    // 本地存储
    localStorage.setItem('todos', JSON.stringify(todos))
}
相关推荐
夜焱辰5 小时前
浏览器端 Agent 的文件版本管理:不用 Git,基于 OPFS + SQLite 自己造了一个
前端·人工智能
梦想的颜色5 小时前
TypeScript 完全指南(下):从类型体操到生产级配置
前端·javascript·typescript
Hi~晴天大圣7 小时前
npm使用介绍
前端·npm·node.js
888CC++8 小时前
如何在 C 语言中进行程序调试?
前端·javascript·算法
喵个咪8 小时前
基于 Taro 的 Headless CMS 多端前端架构:技术解析与二次开发导引
前端·react.js·taro
狂炫冰美式8 小时前
你还在古法PPT吗,试试HTML呢?免费编辑导出工具给 xdm 放这了
前端·后端·github
万少9 小时前
未来组织的分水岭不是员工数量,而是人才密度
前端·后端·面试
任磊abc9 小时前
nextjs16配置eslint+prettier
前端·eslint·nextjs·prettier
x***r1519 小时前
Another-Redis-Desktop-Manager.1.3.7安装步骤详解(附Redis可视化连接与Key管理教程)
前端·bootstrap·html
Captaincc9 小时前
你真的知道自己把 AI 用在了哪里吗?这是 Vibe Usage 想回答的问题
前端·vibecoding