3 回答

TA貢獻1828條經驗 獲得超3個贊
這是因為你沒有跟蹤哪些任務已完成,而只是在推動字符串。對于您的createTask方法,您需要推送一個具有完成屬性的對象來指示哪些任務已完成,如下所示
createTask(task) {
if (task.trim().length === 0) {
return;
}
this.tasks.push({title: task, done: false});
this.render();
}
更新渲染以考慮已完成的任務
render() {
this.ul.innerHTML = "";
this.tasks.forEach((task) => {
const li = document.createElement("li");
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", (e) => {
this.markTask(e);
});
li.appendChild(cb);
li.append(document.createTextNode(task.title));
const btn = document.createElement("button");
li.appendChild(btn);
btn.textContent = "Delete";
btn.classList.add("remove");
btn.addEventListener("click", (e) => {
this.deleteTask(e);
});
this.ul.appendChild(li);
if (task.done) {
cb.checked = true;
li.style.textDecoration = "line-through";
} else {
cb.checked = false;
li.style.textDecoration = "none";
}
});
}
在你的構造函數中更新你的任務變量以查看其效果
constructor() {
this.input = document.getElementById("input");
this.ul = document.getElementById("ul");
this.form = document.getElementById("form");
this.tasks = [{title: 'mill', done: true}, {title: 'jus', done: false}];
this.registerEvent();
}
希望您能了解總體思路。我不會完成整個實現,markTask因為這應該足以讓您了解解決方案應該是什么。祝你好運。

TA貢獻1982條經驗 獲得超2個贊
如果可以的話,我對你的代碼做了一些修改。
您需要的技術是事件委托:對子元素的任何單擊也是對其父元素的單擊。我們在父元素上放置事件偵聽器,然后查看它發生在哪個子元素上。就您而言,這只會為您的所有“刪除”按鈕創建一個事件偵聽器。
另一個想法是不要忽略 DOM,它還保留任務列表,您不需要將它們保存在內存中的表中,這是多余的。
這是代碼:css也是有幫助的
class Todo
{
constructor()
{
this.form = document.getElementById('todo-form')
this.liste = document.getElementById('todo-list')
this.form.onsubmit = e => this.addTask(e)
this.liste.onclick = e => this.delTask(e)
}
addTask(e)
{
e.preventDefault()
if (this.form.task.value.trim() === '') return
let li = document.createElement('li')
, cb = document.createElement('input')
, sp = document.createElement('span')
, bt = document.createElement('button')
;
cb.type = 'checkbox'
sp.textContent = this.form.task.value
bt.textContent = 'Delete'
bt.className = 'remove'
li.appendChild(cb)
li.appendChild(sp)
li.appendChild(bt)
this.liste.appendChild(li)
this.form.reset()
}
delTask(e)
{
if (!e.target.matches('button.remove')) return // reject others clicks
e.target.closest('li').remove()
}
}
new Todo();
#todo-list li > span {
display : inline-block;
background-color : whitesmoke;
width : 20em;
}
#todo-list li input[type=checkbox]:checked + span {
text-decoration : line-through;
}
#todo-list li button.remove {
font-size: .6em;
}
<form id="todo-form">
<input name="task">
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
正如您所看到的,這段代碼更短。您還可以使用 IIFE 而不是類,如下所示:
(function() // IIFE
{
let form = document.getElementById('todo-form')
, liste = document.getElementById('todo-list')
;
form.onsubmit = e => // addTask
{
e.preventDefault()
if (form.task.value.trim() === '') return
let li = document.createElement('li')
, cb = document.createElement('input')
, sp = document.createElement('span')
, bt = document.createElement('button')
;
cb.type = 'checkbox'
sp.textContent = form.task.value
bt.textContent = 'Delete'
bt.className = 'remove'
li.appendChild(cb)
li.appendChild(sp)
li.appendChild(bt)
liste.appendChild(li)
form.reset()
}
liste.onclick = e => // delTask
{
if (!e.target.matches('button.remove')) return // reject others clicks
e.target.closest('li').remove()
}
}
)()
btTaskList.onclick = e =>
{
let tasks = [...document.querySelectorAll('#todo-list li')].map(li=>
{
let val = li.querySelector('span').textContent
, chk = li.querySelector('input[type=checkbox]').checked
;
return {val,chk}
})
console.clear()
console.log( tasks )
}
#todo-list li > span {
display : inline-block;
background-color : whitesmoke;
width : 20em;
}
#todo-list li input[type=checkbox]:checked + span {
text-decoration : line-through;
}
#todo-list li button.remove {
font-size: .6em;
}
<form id="todo-form">
<input name="task">
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
<button id="btTaskList">get task list</button>
我還添加了一個get task list
按鈕...

TA貢獻1777條經驗 獲得超3個贊
標記元素后,您僅更改元素的 Stayle 和屬性。但是刪除后,您會使用render整個列表重新創建,并且render您不會渲染checked參數。
你的渲染應該是:
render() {
this.ul.innerHTML = "";
this.tasks.forEach((task) => {
const li = document.createElement("li");
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", (e) => {
this.markTask(e);
});
li.appendChild(cb);
// missed rendering checked
if (task.checked) {
li.style.textDecoration = "line-through";
cb.checked = 'checked';
}
li.append(document.createTextNode(task));
const btn = document.createElement("button");
li.appendChild(btn);
btn.textContent = "Delete";
btn.classList.add("remove");
btn.addEventListener("click", (e) => {
this.deleteTask(e);
});
this.ul.appendChild(li);
});
}
添加回答
舉報