I'm trying to create a simple todo list app as part of an online tutorial by DevEd, but am getting stuck on one seemingly puzzleing error.
Using the following HTML markup:
<div >
<ul ></ul>
</div>
.. alongside some javascript to create and insert some list elements, I'm then using the following function to filter by todo list entries that have a specific class tag.
function filterTodo(e) {
const todos = todoList.childNodes;
todos.forEach(function (todo) {
switch (e.target.value) {
case "all":
todo.style.display = "flex";
break;
case "completed":
if (todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
}
});
}
All the above seem to work together fine, until I added ANYTHING, even a comment line in between the <ul></ul>
tags like below:
<div >
<ul >
<!-- boo -->
</ul>
</div>
Upon doing this I get the following error when trying to filter the entries:
Uncaught TypeError: Cannot read properties of undefined (reading 'contains')
Can anyone please explain?
Full code found here: https://github.com/developedbyed/vanilla-todo (not my repo)
CodePudding user response:
childNodes
returns a collection of - as it sounds like - child nodes. Some of these nodes may not be elements, but text nodes - and text nodes have no classList
property. For example:
const childNodes = document.querySelector('.container').childNodes;
console.log(childNodes[0].classList);
console.log(childNodes[1].classList);
<div >text node<span>element</span></div>
Use .children
instead, which will retrieve only child elements.
function filterTodo(e) {
[...todoList.children].forEach(function (todo) {