Así que estoy creando una pequeña aplicación usando vainilla javascript, esta aplicación es una lista de tareas pendientes con alguna funcionalidad, tengo un error cuando presiono el filtro aquí está el código javascript:
function filterTodo(e) { const todos = todoList.childNodes; // console.log(todos); 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; case "uncompleted": if (!todo.classList.contains("completed")) { todo.style.display = "flex"; } else { todo.style.display = "none"; } break; } }); } <form> <input type="text" class="todo-input"> <button class="todo-button" type="submit"> <i class="fas fa-plus-square"></i> </button> <div class="select"> <select name="todos" class="filter-todo"> <option value="all">All</option> <option value="completed">Completed</option> <option value="uncompleted">Uncompleted</option> </select> </div> </form> <div class="todo-container"> <ul class="todo-list"> </ul> </div>Aquí hay una imagen del error: [Este error sigue apareciendo cuando presiono el filtro][1] [1]: https://i.stack.imgur.com/63CXI.png
No puedo encontrar mi error, pero creo que (todo) no está identificado en la función anónima o hay un error con la función forEach. por favor ayuda y gracias.
Nota: Aquí está la URL de toda la aplicación en github: https://github.com/Shtaiwee1/Web_fund_additional_apps/tree/master/To_do_list
Simplemente puede cambiar la clase de su lista (el <ul> no el <li> ) y dejar que la cascada de CSS se encargue del resto. .forEach() definitivamente no es necesario ni ninguna matriz o NodeList para el caso. Además, siempre debe tener un default en un switch() ; en este ejemplo, default elimina ambas clases de <ul> (no importa si la clase está realmente allí o no, por lo que cubrir ambas es 100% sin cálculos involucrados). Por cierto, "hacer clic" está bien en esta situación, pero debe usar el evento "cambiar" ya que está diseñado para controles de formulario como <select> .
const form = document.forms[0]; const select = form.elements.filter; select.addEventListener('change', filterList); function filterList(e) { const select = e.target; const list = document.querySelector('.list'); if (select.matches('#filter')) { switch (select.value) { case 'done': list.classList.remove('open'); list.classList.add('done'); break; case 'open': list.classList.remove('done'); list.classList.add('open'); break; default: list.classList.remove('done'); list.classList.remove('open'); break; } } }; li.open::before { content: '⬛' } li.done::before { content: '☑️' } .list.open li.done { display: none } .list.done li.open { display: none } <form> <select id='filter'> <option default value=''>All</option> <option value='done'>Completed</option> <option value='open'>Uncompleted</option> </select> <ul class='list'> <li class='done'>Task</li> <li class='open'>Task</li> <li class='done'>Task</li> <li class='done'>Task</li> <li class='open'>Task</li> <li class='done'>Task</li> <li class='open'>Task</li> <li class='open'>Task</li> <li class='done'>Task</li> </ul> </form>Para mostrar/ocultar su lista de "cosas por hacer", puede simplificar esto usando atributos de datos y luego cambiarlos. Aquí usé uno para el estado de "acción" y el otro para mostrar/ocultar en función de eso.
function filterTodo(event) { event.preventDefault(); let todoList = document.querySelector(".todo-list"); let todoSelect = document.querySelector(".filter-todo"); const todos = todoList.querySelectorAll(".todo-item"); let val = event.target.value; todos.forEach(function(todo) { todo.dataset.status = todo.dataset.action === val && val !== "all" ? val : val === "all" ? "" : "none"; }); } let b = document.querySelector(".todo-button"); b.addEventListener('click', filterTodo); let sel = document.querySelector(".filter-todo"); sel.addEventListener('change', filterTodo); .todo-container, .todo-container .todo-list { border: solid 1px lime; display: flex; flex-direction: column; } .todo-item { display: flex; background-color: #40404010; border: 1px solid #40404040; margin: 0.5em; } .todo-item[data-status="completed"] { background-color: #10401010; } .todo-item[data-action="completed"]::before { content: "DONE: "; color: green; } .todo-item[data-status="completed"] span { color: lime; } .todo-item[data-status="uncompleted"] { background-color: #40101010; text-decoration-line: underline overline; } .todo-item[data-status="none"] { display: none; text-decoration-color: red; text-decoration-style: solid; text-decoration-line: underline; } .todo-item[data-status=""] { text-decoration-color: cyan; text-decoration-style: solid; text-decoration-line: underline; } <form> <input type="text" class="todo-input" /> <button class="todo-button" type="submit"> <i class="fas fa-plus-square">[+]</i> </button> <div class="select-container"> <select name="todos" class="filter-todo"> <option value="all">All</option> <option value="completed">Completed</option> <option value="uncompleted">Uncompleted</option> </select> </div> </form> <div class="todo-container"> <ul class="todo-list"> <li class="todo-item">Get a new cat: I have no status or action</li> <li class="todo-item" data-action="completed" data-status="completed">Get a new Hippo</li> <li class="todo-item" data-action="uncompleted" data-status="uncompleted">Send MORE money!</li> <li class="todo-item" data-status="none">Send me money! I was hidden?</li> <li class="todo-item" data-status="fish">Send me money! fish?</li> <li class="todo-item" data-status="">Get to the bank NOW!</li> </ul> </div>