<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todo</title>
</head>
<body>
<header>
<h3>待定事项</h3>
</header>
<main>
<ul id="todoList"></ul>
<input type="text" id="content">
<button id="confirm">确认</button>
</main>
<script>
(function () {
const ADD_KEY = '__todoList__'
const Utils = {
// 模拟 Modal(实体模型)
store(key, data) {
if (arguments.length > 1) {
return localStorage.setItem(key, JSON.stringify(data));
} else {
let storeData = localStorage.getItem(key);
return (storeData && JSON.parse(storeData)) || []; // 这里一定要设置初始值为 []
}
}
}
class Todo {
constructor(id, text = "") {
this.id = id
this.text = text
}
}
let App = {
init() {
// this.todos 为一个存储json对象的数组, 是一个实例化的数据对象,可任意调用
this.todos = Utils.store(ADD_KEY)
this.findDom()
this.bindEvent()
this.render() // 初始化渲染
},
findDom() {
this.contentBox = document.querySelector("#content")
this.confirm = document.querySelector("#confirm")
this.todoList = document.querySelector("#todoList")
this.todoListItem = document.getElementsByTagName("li")
},
// 模拟 Controller (业务逻辑层)
bindEvent() {
this.confirm.addEventListener('click', () => {
// 要求模型 M 改变状态,add()函数是写入数据操作
this.add()
}, false)
this.todoList.addEventListener('click', (item) => { // 事件委托,优化性能
this.remove(item)
}, false)
},
// 这里勉强抽象成一个视图吧!!!
view() {
let fragment = document.createDocumentFragment() // 减少回流次数
fragment = ''
for (let i = 0; i < this.todos.length; i++) { // 一次性DOM节点生成
// 这里使用拼接字符串代替视图的模板,
// *******注意模板并不是一个视图,模板是由视图定义配置出来的,并被其管理着*******
// 模板是用一种声明的方式指定部分甚至所有的视图对象
fragment += `<li>${this.todos[i].text}</li>`
}
this.todoList.innerHTML = fragment
},
// render()函数作为一个订阅者的回调函数,数据的变化会反馈到模型 store
// 换句话说:视图通过观察者模式,观察模型 store,当模型发生改变,触发视图更新
render() {
this.view()
/**
* 这里需要特别提一下,按照 MVC 原则这里本不应该出现下面的代码的
* 因为业务逻辑关系(我本地存储使用的是同一个key值,再次写入数据会覆盖原来的数据,),
* 所以必须通知模型 M 保存数据, V 层处理了不该它处理的逻辑,导致 M 与 V 耦合
*
* 解决办法是:将其抽象出来编写一个 视图助手 helper
*/
Utils.store(ADD_KEY, this.todos)
},
getItemIndex(item) {
let itemIndex
if (item.target.tagName.toLowerCase() === 'li') {
let arr = Array.prototype.slice.call(this.todoListItem)
let index = arr.indexOf(item.target)
return itemIndex = index
}
},
add(e) {
let id = Number(new Date())
let text = this.contentBox.value
let addTodo = new Todo(id, text)
this.todos.unshift(addTodo) // 模型发生改变
this.render() // 当模型发生改变,触发视图更新
},
remove(item) {
let index = this.getItemIndex(item)
this.todos.splice(index, 1)
this.render()
}
}
App.init()
})()
</script>
</body>
</html>
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有