原生+TS实现todolist效果
中
秋
快
乐
前言
我是歌谣 最好的种树是十年前 其次是现在 原生+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="file" id="fileInput" name="fileInput" multiple> --> <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> // var fileInput = document.getElementById("fileInput"); // var data = document.getElementById("data"); // var files = fileInput.files; // fileInput.addEventListener("change",function(e){ // console.log(e) // for (var i = 0; i < files.length; i++) { // var file = files[i]; // var linode=document.createElement("li") // linode.innerText=file.name // data.append(linode) // } // }) // data.append() // var formData = new FormData(); // for (var i = 0; i < files.length; i++) { // var file = files[i]; // formData.append("files[]", file, file.name); // } </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代理技术深度解析与实战指南