前言
我是歌谣 最好的种树是十年前 其次是现在 原生+TS实现todolist效果
环境配置
| npm init -y |
| yarn add vite -D |
修改page.json配置端口
| { |
| "name": "demo1", |
| "version": "1.0.0", |
| "description": "", |
| "main": "index.js", |
| "scripts": { |
| "dev": "vite --port 3002" |
| }, |
| "keywords": [], |
| "author": "", |
| "license": "ISC", |
| "devDependencies": { |
| "vite": "^4.4.9" |
| } |
| } |
主文件
| <!DOCTYPE html> |
| <html lang="en"> |
| |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Document</title> |
| </head> |
| |
| <body> |
| |
| <diV> |
| |
| <input type="text" id="inputText"> |
| <button id="addBtn">Add</button> |
| </diV> |
| <ul id="todoList"> |
| |
| </ul> |
| <ul id="data"> |
| |
| </ul> |
| <script type="module" src="./index.ts"></script> |
| </body> |
| |
| </html> |
| <script> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| </script> |
index.ts
| |
| interface ITodo { |
| id: number, |
| content: string, |
| completed: boolean |
| } |
| type TypeTarget = HTMLInputElement | HTMLButtonElement |
| type TypeContentMap = { |
| [key: number]: HTMLSpanElement, |
| remove(id:number):void |
| } |
| enum ElementType { |
| CHECKBOX = 'HTMLInputElement', |
| BUTTON = 'HTMLButtonElement' |
| |
| } |
| const oInputText = <HTMLInputElement>document.querySelector('#inputText') |
| const oAddBtn = document.querySelector('#addBtn') |
| const oTodoList = document.querySelector('#todoList') |
| const eventMap = new Map([ |
| [oAddBtn, handleAddBtnClick], |
| [oTodoList, handleListClick], |
| ] |
| ) |
| const contentMap: TypeContentMap = { |
| remove:(id:number)=>delete contentMap[id] |
| } |
| const init = () => { |
| bindEvent() |
| } |
| function bindEvent() { |
| eventMap.forEach((handler, el) => { |
| el?.addEventListener("click", handler, false) |
| }) |
| } |
| function handleAddBtnClick() { |
| const inputText = oInputText.value |
| console.log(1111) |
| if (!inputText.trim().length) return |
| const oTodoItem = CreateTodoItem({ |
| id: new Date().getTime(), |
| content: inputText, |
| completed: false |
| }) |
| oTodoList?.append(oTodoItem) |
| } |
| function handleListClick(e: Event) { |
| const target = <TypeTarget>e.target |
| const type = getObjectType<TypeTarget>(target) |
| if (type === ElementType.CHECKBOX || type === ElementType.BUTTON) { |
| const id = Number(target.dataset.id) |
| switch (type) { |
| case ElementType.CHECKBOX: |
| setContentStyle(id, (<HTMLInputElement>target).checked) |
| break |
| case ElementType.BUTTON: |
| removeTodoItem(id,<HTMLElement>target.parentNode) |
| break; |
| default: |
| break |
| } |
| } |
| |
| } |
| function CreateTodoItem({ id, content, completed }: ITodo) { |
| const oTodoItem = document.createElement("li") |
| oTodoItem.appendChild(createCheckBox(id, completed)) |
| oTodoItem.appendChild(createContent(id, content)) |
| oTodoItem.appendChild(createRemoveBun(id)) |
| return oTodoItem |
| } |
| |
| function createCheckBox(id: number, completed: boolean) { |
| const oCheckBox = document.createElement('input') |
| oCheckBox.type = 'checkbox' |
| oCheckBox.checked = completed |
| oCheckBox.dataset.id = id.toString() |
| return oCheckBox |
| } |
| |
| function createContent(id: number, content: string) { |
| const oContent = document.createElement('span') |
| oContent.innerText = content |
| contentMap[id] = oContent |
| return oContent |
| } |
| |
| function createRemoveBun(id: number) { |
| const oRemoveBtn = document.createElement("button") |
| oRemoveBtn.innerText = 'REMOVE' |
| oRemoveBtn.dataset.id = id.toString() |
| return oRemoveBtn |
| } |
| function removeTodoItem(id:number,item:HTMLElement){ |
| oTodoList?.removeChild(item) |
| contentMap.remove(id) |
| |
| } |
| function getObjectType<T>(value: T): string { |
| return Object.prototype.toString.call(value).match(/\[object (.+?)\]/)[1] |
| } |
| function setContentStyle(id: number, completed: boolean) :void{ |
| contentMap[id].style.textDecoration = completed ? 'line-through' : '' |
| } |
| init() |
运行结果



【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2022-09-30 ts重点学习30-变量声明和解构笔记
2022-09-30 ts重点学习29-变量声明和解构
2022-09-30 ts重点学习28-bigint和symbol笔记
2022-09-30 ts重点学习27-bigint和symbol
2022-09-30 ts重点学习26-枚举笔记
2022-09-30 ts重点学习23-never和object
2022-09-30 ts重点学习25-枚举