当前位置: 首页 > news >正文

东莞做网站哪家好正规的镇江网站建设

东莞做网站哪家好,正规的镇江网站建设,河北抖音seo系统,wordpress不会发送电子邮件项目概述 使用原生JavaScript实现一个功能完善的待办事项列表应用,支持任务的添加、编辑、删除和完成状态切换,并通过localStorage实现数据持久化。 核心功能需求 任务管理:添加、编辑、删除任务状态切换:标记任务完成/未完成&…

项目概述

使用原生JavaScript实现一个功能完善的待办事项列表应用,支持任务的添加、编辑、删除和完成状态切换,并通过localStorage实现数据持久化。

核心功能需求

  1. 任务管理:添加、编辑、删除任务
  2. 状态切换:标记任务完成/未完成,带删除线样式
  3. 数据持久化:使用localStorage保存任务数据
  4. 交互设计:支持回车添加任务,按钮操作

技术栈

  • HTML5:页面结构
  • CSS3:样式设计,包括完成状态样式
  • JavaScript:DOM操作、事件处理、本地存储
  • 本地存储:localStorage API

项目结构

todo-list/
├── index.html      # 主页面
├── css/
│   └── style.css   # 样式文件
├── js/└── app.js      # 核心逻辑

实现思路

1. 数据结构设计

// 任务对象结构
{id: Number,         // 唯一标识符content: String,    // 任务内容completed: Boolean, // 完成状态createdAt: Date     // 创建时间
}// 任务数组
let tasks = [];

2. 核心功能模块

  • DOM操作模块:动态创建任务元素、更新任务列表
  • 事件处理模块:添加、编辑、删除、状态切换事件
  • 本地存储模块:保存、读取、更新本地数据
  • 交互优化模块:回车添加、焦点管理、动画效果

3. 关键技术点实现

  • 动态创建元素:使用document.createElement和appendChild
  • 状态切换:通过classList.toggle(‘completed’)实现样式切换
  • 本地存储:JSON.stringify和JSON.parse处理数据
  • 事件委托:利用事件冒泡机制处理动态元素事件

代码:

  • index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JavaScript待办事项列表</title><link rel="stylesheet" href="css/style.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body><div class="container"><header><h1>待办事项列表 <i class="fas fa-check-circle"></i></h1><p>管理你的任务,提高工作效率</p></header><div class="task-input"><input type="text" id="taskInput" placeholder="添加新任务..."><button id="addTaskBtn"><i class="fas fa-plus"></i> 添加任务</button></div><div class="task-stats"><span>剩余任务: <strong id="remainingTasks">0</strong></span><button id="clearCompletedBtn"><i class="fas fa-trash"></i> 清除已完成</button></div><ul id="taskList" class="task-list"><!-- 任务项将通过JavaScript动态生成 --><li class="task-item placeholder"><span>你的任务将显示在这里</span></li></ul></div><script src="js/app.js"></script>
</body>
</html>
  • style.css
/* 基础样式重置 */
.container{background-color: #ebf2fa;
}
* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}body {background-color: #f5f5f5;color: #333;line-height: 1.6;
}.container {max-width: 800px;margin: 0 auto;padding: 20px;
}header {text-align: center;margin-bottom: 30px;padding-bottom: 20px;border-bottom: 1px solid #eee;
}header h1 {font-size: 2.5rem;margin-bottom: 10px;color: #2c3e50;
}header p {color: #7f8c8d;font-size: 1.1rem;
}/* 任务输入区域 */
.task-input {display: flex;gap: 10px;margin-bottom: 25px;
}.task-input input {flex: 1;padding: 12px 15px;border: 2px solid #ddd;border-radius: 6px;font-size: 1rem;transition: all 0.3s ease;
}.task-input input:focus {outline: none;border-color: #3498db;box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}.task-input button {padding: 12px 20px;background-color: #3498db;color: white;border: none;border-radius: 6px;cursor: pointer;font-size: 1rem;transition: background-color 0.3s ease;display: flex;align-items: center;gap: 8px;
}.task-input button:hover {background-color: #2980b9;
}/* 任务统计区域 */
.task-stats {display: flex;justify-content: space-between;align-items: center;margin-bottom: 20px;padding: 10px 15px;background-color: #fff;border-radius: 6px;box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}.task-stats span {color: #7f8c8d;font-size: 0.95rem;
}.task-stats strong {color: #2c3e50;
}.task-stats button {background-color: transparent;color: #e74c3c;border: none;cursor: pointer;font-size: 0.95rem;display: flex;align-items: center;gap: 5px;padding: 5px 10px;border-radius: 4px;transition: all 0.2s ease;
}.task-stats button:hover {background-color: rgba(231, 76, 60, 0.1);
}/* 任务列表 */
.task-list {list-style: none;margin-top: 20px;
}.task-item {background-color: white;padding: 15px;border-radius: 6px;margin-bottom: 10px;display: flex;align-items: center;gap: 15px;box-shadow: 0 2px 4px rgba(0,0,0,0.05);transition: transform 0.2s ease, box-shadow 0.2s ease;
}.task-item:hover {transform: translateY(-2px);box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}.task-item.placeholder {background-color: rgba(255,255,255,0.5);justify-content: center;color: #95a5a6;padding: 40px 20px;
}/* 任务复选框 */
.task-checkbox {width: 22px;height: 22px;border-radius: 50%;border: 2px solid #ddd;cursor: pointer;display: flex;align-items: center;justify-content: center;flex-shrink: 0;transition: all 0.3s ease;
}.task-checkbox:hover {border-color: #3498db;
}.task-checkbox.checked {background-color: #2ecc71;border-color: #2ecc71;
}/* 任务内容 */
.task-content {flex: 1;transition: color 0.3s ease, text-decoration 0.3s ease;font-size: 1.05rem;
}.task-item.completed .task-content {text-decoration: line-through;color: #95a5a6;
}/* 任务操作按钮 */
.task-actions {display: flex;gap: 8px;
}.task-btn {background: none;border: none;cursor: pointer;font-size: 1rem;padding: 5px;border-radius: 4px;transition: all 0.2s ease;display: flex;align-items: center;justify-content: center;
}.edit-btn {color: #f39c12;
}.edit-btn:hover {background-color: rgba(243, 156, 18, 0.1);
}.delete-btn {color: #e74c3c;
}.delete-btn:hover {background-color: rgba(231, 76, 60, 0.1);
}/* 响应式设计 */
@media (max-width: 600px) {.task-input {flex-direction: column;}.task-input button {width: 100%;justify-content: center;}.task-stats {flex-direction: column;align-items: stretch;gap: 10px;}.task-stats button {width: 100%;justify-content: center;}
}
  • app.js
// 任务数据存储
let tasks = [];// DOM元素
const taskInput = document.getElementById('taskInput');
const addTaskBtn = document.getElementById('addTaskBtn');
const taskList = document.getElementById('taskList');
const remainingTasksEl = document.getElementById('remainingTasks');
const clearCompletedBtn = document.getElementById('clearCompletedBtn');
const placeholderEl = document.querySelector('.placeholder');// 初始化应用
function init() {// 从本地存储加载任务loadTasks();// 渲染任务列表renderTasks();// 绑定事件监听器bindEvents();
}// 从本地存储加载任务
function loadTasks() {const storedTasks = localStorage.getItem('tasks');if (storedTasks) {tasks = JSON.parse(storedTasks);}
}// 保存任务到本地存储
function saveTasks() {localStorage.setItem('tasks', JSON.stringify(tasks));
}// 渲染任务列表
function renderTasks() {// 清空任务列表taskList.innerHTML = '';// 检查是否有任务if (tasks.length === 0) {taskList.appendChild(placeholderEl);remainingTasksEl.textContent = '0';return;}// 隐藏占位符if (placeholderEl.parentNode === taskList) {taskList.removeChild(placeholderEl);}// 渲染每个任务tasks.forEach(task => {const taskElement = createTaskElement(task);taskList.appendChild(taskElement);});// 更新剩余任务数量updateRemainingTasks();
}// 创建任务元素
function createTaskElement(task) {const li = document.createElement('li');li.className = `task-item ${task.completed ? 'completed' : ''}`;li.dataset.taskId = task.id;li.innerHTML = `<div class="task-checkbox ${task.completed ? 'checked' : ''}">${task.completed ? '<i class="fas fa-check"></i>' : ''}</div><div class="task-content" contenteditable="false">${escapeHTML(task.content)}</div><div class="task-actions"><button class="task-btn edit-btn" title="编辑任务"><i class="fas fa-edit"></i></button><button class="task-btn delete-btn" title="删除任务"><i class="fas fa-trash"></i></button></div>`;return li;
}// 添加新任务
function addTask(content) {if (!content.trim()) return; // 忽略空任务const newTask = {id: generateId(),content: content.trim(),completed: false,createdAt: new Date().toISOString()};tasks.unshift(newTask); // 添加到数组开头saveTasks();renderTasks();// 清空输入框taskInput.value = '';// 聚焦输入框taskInput.focus();
}// 切换任务完成状态
function toggleTaskCompletion(taskId) {const task = tasks.find(t => t.id === taskId);if (task) {task.completed = !task.completed;saveTasks();renderTasks();}
}// 编辑任务内容
function editTask(taskId, newContent) {const task = tasks.find(t => t.id === taskId);if (task && newContent.trim()) {task.content = newContent.trim();saveTasks();renderTasks();}
}// 删除任务
function deleteTask(taskId) {tasks = tasks.filter(task => task.id !== taskId);saveTasks();renderTasks();
}// 清除所有已完成任务
function clearCompletedTasks() {tasks = tasks.filter(task => !task.completed);saveTasks();renderTasks();
}// 更新剩余任务数量
function updateRemainingTasks() {const remaining = tasks.filter(task => !task.completed).length;remainingTasksEl.textContent = remaining;
}// 绑定事件监听器
function bindEvents() {// 添加任务按钮点击事件addTaskBtn.addEventListener('click', () => {addTask(taskInput.value);});// 输入框回车事件taskInput.addEventListener('keypress', (e) => {if (e.key === 'Enter') {addTask(taskInput.value);}});// 任务列表事件委托taskList.addEventListener('click', (e) => {const taskItem = e.target.closest('.task-item');if (!taskItem || taskItem.classList.contains('placeholder')) return;const taskId = parseInt(taskItem.dataset.taskId);// 切换完成状态if (e.target.closest('.task-checkbox')) {toggleTaskCompletion(taskId);}// 删除任务if (e.target.closest('.delete-btn')) {deleteTask(taskId);}// 编辑任务if (e.target.closest('.edit-btn')) {const contentEl = taskItem.querySelector('.task-content');enableEditMode(contentEl, taskId);}});// 双击任务内容编辑taskList.addEventListener('dblclick', (e) => {const contentEl = e.target.closest('.task-content');if (contentEl) {const taskItem = contentEl.closest('.task-item');const taskId = parseInt(taskItem.dataset.taskId);enableEditMode(contentEl, taskId);}});// 清除已完成按钮点击事件clearCompletedBtn.addEventListener('click', clearCompletedTasks);
}// 启用编辑模式
function enableEditMode(contentEl, taskId) {// 移除所有任务的编辑状态document.querySelectorAll('.task-content').forEach(el => {el.contentEditable = 'false';el.classList.remove('editing');});// 设置当前任务为编辑状态contentEl.contentEditable = 'true';contentEl.classList.add('editing');contentEl.focus();// 保存编辑内容const saveEdit = (e) => {if (e.type === 'blur' || (e.type === 'keydown' && e.key === 'Enter')) {e.preventDefault();editTask(taskId, contentEl.textContent);contentEl.contentEditable = 'false';contentEl.classList.remove('editing');// 移除事件监听器contentEl.removeEventListener('blur', saveEdit);contentEl.removeEventListener('keydown', saveEdit);}};// 添加事件监听器contentEl.addEventListener('blur', saveEdit);contentEl.addEventListener('keydown', saveEdit);
}// 生成唯一ID
function generateId() {return Date.now() + Math.floor(Math.random() * 1000);
}// HTML转义
function escapeHTML(str) {return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
}// 初始化应用
document.addEventListener('DOMContentLoaded', init);

效果展示:
在这里插入图片描述

http://www.dtcms.com/a/455928.html

相关文章:

  • 做网站的成本哪些因素营销网站权重
  • 网站首页面设计代码wordpress插件随机文章
  • 唯美谷智能网站建设系统营销网站主题有哪些
  • 做网站需要先申请域名获取网站目录下所有文件
  • o2o系统网站建设电子商务作业做网站
  • asp技校网站wordpress单选框
  • 做ic的电子网站有哪些黄页88网官网首页
  • 青岛网站设计价格网页升级紧急通知怎么取消
  • python做网站的书建设一个网站需要哪些方面的开支
  • 如皋市网站建设潍坊网站公司网络科技
  • 网站建设7茶叶企业网站开发源码
  • 网站框架图怎么做WordPress付费阅读文章
  • 产品微信网站建设wordpress 导出export.php
  • 长沙专业网站建设公司成都锐度设计公司怎么样
  • 做网站推广贵阳企业网站模板
  • 台州网站排名外包有没有专门做渔具的网站
  • 河南省住房城乡建设厅官方网站淄博制作网站的公司
  • 衡阳城乡建设部网站首页建设旅游网站
  • 烟台网站制作厂家联系方式私人做网站要多少钱
  • 做电影网站不放国内主机wordpress 重复插件
  • 专业做装修的网站网页设计怎么让图片横向填满
  • 做公司网站的企业灰色行业推广平台网站
  • 怎么建小说网站成品软件网站推荐
  • o2o电商网站建设电商哪个岗位最吃香
  • 黄骅广信建设集团网站wordpress帖子打赏观看
  • 有的网站打不开 但别人电脑能打开国产oa系统有哪些
  • 织梦做分销网站自己建立一个网页
  • 360老是提示危险网站营销策划模板
  • 建设银行个人登录网站备案信息修改网站名称
  • 北京市保障性住建设投资中心网站首页专门做dm单的网站