简体   繁体   English

一个简单的todoApp复选框问题

[英]A simple todoApp checkbox issue

I have a simple todoApp about DOM manipulation. 我有一个关于DOM操作的简单todoApp。

 const classNames = { TODO_ITEM: 'todo-container', TODO_CHECKBOX: 'todo-checkbox', TODO_TEXT: 'todo-text', TODO_DELETE: 'todo-delete', } const list = document.getElementById('todo-list') const itemCountSpan = document.getElementById('item-count') const uncheckedCountSpan = document.getElementById('unchecked-count') let count = 0; let checkedCount = 0; let todo; function newTodo() { todo = prompt("Please enter to do task","enter here") count++; const markup = `<li><input type="checkbox" id=${todo} name="feature" value=${todo} data-ischecked = "false" /> <label for=${todo}>${todo}</label></li>` list.insertAdjacentHTML("beforeend",markup) itemCountSpan.innerHTML = count; document.getElementById(todo).addEventListener("click",check); } function check(){ let article = document.getElementById(todo); if(article.dataset.ischecked == "false"){ article.dataset.ischecked = "true"; checkedCount++; uncheckedCountSpan.innerHTML = checkedCount } else{ article.dataset.ischecked = "false"; checkedCount--; uncheckedCountSpan.innerHTML = checkedCount } } 
 <!DOCTYPE html> <html> <head> <title>TODO App</title> <link rel="stylesheet" type="text/css" href="./styles.css" /> </head> <body> <div class="container center"> <h1 class="center title">My TODO App</h1> <div class="flow-right controls"> <span>Item count: <span id="item-count">0</span></span> <span>Unchecked count: <span id="unchecked-count">0</span></span> </div> <button class="button center" onClick="newTodo()">New TODO</button> <ul id="todo-list" class="todo-list"></ul> </div> <script src="./script.js"></script> </body> </html> 

However, the checked feature is not what I expected. 但是,选中的功能不是我所期望的。 When I click on the checkbox, the total value should increase/decrease accordingly, but the number is toggling between 0 and 1. 当我单击复选框时,总值应相应增加/减少,但是数字在0和1之间切换。

What is the way to fix this? 解决此问题的方法是什么? thank you 谢谢

Why Yours Is Not Working 为什么你的不工作

You're storing the most recently added item's ID as a variable called todo . 您会将最新添加的商品ID存储为名为todo的变量。 That means in your check() function, the line... 这意味着在您的check()函数中,该行...

let article = document.getElementById(todo); 

...will always refer to the last item added . ...将始终引用最后添加的项目 It's just toggling the data-ischecked back and forth on whichever the last item is. 它只是在最后一项上data-ischecked来回切换data-ischecked


How To Fix It 如何修复

You want the click event to refer to the checkbox that's being clicked . 您希望click事件引用被单击的复选框。 We can do this by adding a parameter to the check() function, called event . 我们可以通过在check()函数中添加一个名为event的参数来实现。 With this, event.target will allow us to refer to the element that's been clicked. 这样, event.target将允许我们引用被单击的元素。

function check(event) {
    let article = event.target; //This is the clicked checkbox!
}

(Given this, the todo variable no longer needs to be global.) (鉴于此, todo变量不再需要是全局的。)


One Other Important Note 另一个重要说明

I'd highly advise against using todo as the element ID, because your ID cannot have spaces in it. 我强烈建议您不要将todo用作元素ID,因为您的ID中不能包含空格。 Any time a to-do is entered with a space, your current code will throw an error. 每当在待办事项中输入空格时,您当前的代码都会引发错误。

Given that you're not allowing the removal of items, you could set it to something like "todo-" + count so that your IDs would be todo-0 , todo-1 , todo-2 , etc. 鉴于您不允许删除项目,可以将其设置为"todo-" + count类的东西,以便您的ID为todo-0todo-1todo-2等。

I've implemented this in the code below as well, allowing you to add spaces in your to-do items. 我也在下面的代码中实现了这一点,允许您在待办事项中添加空格。

 const classNames = { TODO_ITEM: 'todo-container', TODO_CHECKBOX: 'todo-checkbox', TODO_TEXT: 'todo-text', TODO_DELETE: 'todo-delete', } const list = document.getElementById('todo-list') const itemCountSpan = document.getElementById('item-count') const uncheckedCountSpan = document.getElementById('unchecked-count') let count = 0; let checkedCount = 0; function newTodo() { var todo = prompt("Please enter to do task", "enter here"); var newId = "todo" + count; count++; const markup = `<li><input type="checkbox" id=${newId} name="feature" value=${todo} data-ischecked = "false" /> <label for=${todo}>${todo}</label></li>` list.insertAdjacentHTML("beforeend", markup) itemCountSpan.innerHTML = count; document.getElementById(newId).addEventListener("click", check); } function check(event) { let article = event.target; if (article.dataset.ischecked == "false") { article.dataset.ischecked = "true"; checkedCount++; uncheckedCountSpan.innerHTML = checkedCount } else { article.dataset.ischecked = "false"; checkedCount--; uncheckedCountSpan.innerHTML = checkedCount } } 
 <!DOCTYPE html> <html> <head> <title>TODO App</title> <link rel="stylesheet" type="text/css" href="./styles.css" /> </head> <body> <div class="container center"> <h1 class="center title">My TODO App</h1> <div class="flow-right controls"> <span>Item count: <span id="item-count">0</span></span> <span>Unchecked count: <span id="unchecked-count">0</span></span> </div> <button class="button center" onClick="newTodo()">New TODO</button> <ul id="todo-list" class="todo-list"></ul> </div> <script src="./script.js"></script> </body> </html> 


Yo need to pass a reference to the checked element. 您需要传递对选中元素的引用。 Something like this: 像这样:

...
function check(evt){
    let article = document.getElementById(evt.target.id);
...
}

Then yor snippet will work: 然后您的代码片段将起作用:

 const classNames = { TODO_ITEM: 'todo-container', TODO_CHECKBOX: 'todo-checkbox', TODO_TEXT: 'todo-text', TODO_DELETE: 'todo-delete', } const list = document.getElementById('todo-list') const itemCountSpan = document.getElementById('item-count') const uncheckedCountSpan = document.getElementById('unchecked-count') let count = 0; let checkedCount = 0; let todo; function newTodo() { todo = prompt("Please enter to do task","enter here") count++; const markup = `<li><input type="checkbox" id=${todo} name="feature" value=${todo} data-ischecked = "false" /> <label for=${todo}>${todo}</label></li>` list.insertAdjacentHTML("beforeend",markup) itemCountSpan.innerHTML = count; document.getElementById(todo).addEventListener("click",check); } function check(evt){ let article = document.getElementById(evt.target.id); if(article.dataset.ischecked == "false"){ article.dataset.ischecked = "true"; checkedCount++; uncheckedCountSpan.innerHTML = checkedCount } else{ article.dataset.ischecked = "false"; checkedCount--; uncheckedCountSpan.innerHTML = checkedCount } } 
 <!DOCTYPE html> <html> <head> <title>TODO App</title> <link rel="stylesheet" type="text/css" href="./styles.css" /> </head> <body> <div class="container center"> <h1 class="center title">My TODO App</h1> <div class="flow-right controls"> <span>Item count: <span id="item-count">0</span></span> <span>Unchecked count: <span id="unchecked-count">0</span></span> </div> <button class="button center" onClick="newTodo()">New TODO</button> <ul id="todo-list" class="todo-list"></ul> </div> <script src="./script.js"></script> </body> </html> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM