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))
}
相关推荐
mldong9 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排10 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby606110 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角12 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!12 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰12 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi13 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen14 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马15 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu15 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss