介绍:
在输入框中输入待办事项,点击回车,TodoList 里增加一条Todo,如果点击回车时输入框未聚焦则无效。
点击某条Todo,可更改状态,右击可删除此条Todo。
添加、删除Todo以及Todo的当前状态都将保存在 localStroage中,进入页面时会渲染到页面上。
我用了两个方法
- 第一种:在添加Todo时,给每个Todo 的 li 标签添加属性 key (获取当前Todo是第几个),在更改 Todo 状态时根据 key 获取缓存对应的某条数据,然后修改状态值。
- 这个方法不好,这样使用key值很不优雅。并且当时没考虑删除的情况,如果删除的话,key值将很混乱。
- 第二种:在更改 Todo 状态时,遍历当前所有 Todo 的节点,获取每个 Todo 的文案和状态,更新缓存的值。
html:
<header>
<h1>TodoList</h1>
</header>
<div>
<input type="text" placeholder="Enter your todo" id="todo_input">
<ul id="todo_list"></ul>
</div>
css:
.complete{
color: gray;
text-decoration: line-through ;
}
.not_complete{
color:black;
}
#todo_list li{
cursor: pointer;
}
下面两种方案的 js 代码都列出
第一种(不推荐)
var input = document.querySelector('#todo_input');
var inputList = document.querySelector('#todo_list');
var todoListData = [];
//取缓存
var storageList = localStorage.getItem('list');
if (storageList) {
todoListData = JSON.parse(storageList);
JSON.parse(storageList).forEach(function (v) {
var li = document.createElement('li');
li.innerText = v.text;
v.complete ? li.classList.add('complete') : li.classList.add('not_complete');
li.setAttribute('key', v.key);
inputList.appendChild(li);
});
}
// 键盘事件
document.addEventListener('keydown', function (e) {
// 判断输入框是否处于聚焦状态
if (input == document.activeElement) {
if (e.key === 'Enter') {
//判断是否按下Enter键盘
var li = document.createElement('li');
var inputValue = input.value;
if (inputValue.trim().length > 0) {
li.innerText = inputValue;
li.classList.add('not_complete');
var key = document.querySelectorAll('#todo_list li').length || 0;
li.setAttribute('key', key + '');
inputList.appendChild(li);
todoListData.push({
text: inputValue,
complete: false,
key: key
});
localStorage.setItem('list', JSON.stringify(todoListData));
input.value = '';
}
}
}
});
// 点击列表项
inputList.addEventListener('click', function (e) {
var li = e.target;
var key = li.getAttribute('key');
li.classList.toggle('complete');
li.classList.toggle('not_complete');
todoListData[key].complete = !todoListData[key].complete;
localStorage.setItem('list', JSON.stringify(todoListData));
});
第二种(✅ 推荐):
var input = document.querySelector('#todo_input');
var inputList = document.querySelector('#todo_list');
var todoListData = [];
//取缓存
var storageList = localStorage.getItem('list');
if (storageList) {
todoListData = JSON.parse(storageList);
todoListData.forEach(function (v) {
var li = document.createElement('li');
li.innerText = v.text;
v.complete ? li.classList.add('complete') : li.classList.add('not_complete');
inputList.appendChild(li);
});
}
// 键盘事件
document.addEventListener('keydown', function (e) {
// 判断输入框是否处于聚焦状态
if (input == document.activeElement) {
if (e.key === 'Enter') {
var li = document.createElement('li');
var inputValue = input.value;
if (inputValue.trim().length > 0) {
li.innerText = inputValue;
li.classList.add('not_complete');
inputList.appendChild(li);
todoListData.push({
text: inputValue,
complete: false
});
localStorage.setItem('list', JSON.stringify(todoListData));
input.value = '';
}
}
}
});
// 点击列表项,标记完成/未完成
inputList.addEventListener('click', function (e) {
var li = e.target;
li.classList.toggle('complete');
li.classList.toggle('not_complete');
updateTodoList();
});
// 右击列表项,删除
inputList.addEventListener('contextmenu', function (e) {
e.preventDefault();
var li = e.target;
li.remove();
updateTodoList();
});
// 更新缓存中的todo数据
function updateTodoList() {
var todosEl = document.querySelectorAll('li');
var todos = [];
todosEl.forEach(function (e) {
todos.push({
text: e.innerText,
complete: e.classList.contains('complete')
});
});
localStorage.setItem('list', JSON.stringify(todos));
}