Todo应用中new-todo表单不显示问题求助
问题排查与解决
我一眼就找到问题根源了——你的表单嵌套在#todos容器里,而你的renderNotes函数每次执行都会通过document.querySelector('#todos').innerHTML = ''清空这个容器的所有内容,包括里面的表单!
为什么脚本位置会影响显示?
- 当脚本放在表单之前时:页面加载时先执行JS,
renderNotes会清空#todos(此时表单还没被浏览器解析出来,第一次清空不影响),但之后表单被渲染到#todos里,只要触发renderNotes(比如输入搜索内容),就会再次清空容器,把表单删掉,导致你看不到它。 - 当脚本放在表单之后时:大概率你无意中把表单移出了
#todos容器,清空操作不会影响到表单,它就能正常显示了。
两种解决方案
方案1:调整HTML结构(最简单)
把表单从#todos容器里移出来,让它成为独立的部分,这样renderNotes清空todo列表时就不会碰它:
<div id="div-1"> <h1>Todo-App</h1> <button>Add a new ToDo</button> <br> <br> <input id="search-text" type="text" placeholder="Search todo"> <!-- 把表单移到#todos外面 --> <form id="new-todo"> <input type="text" placeholder="hiya" name="text"> <button>pressss</button> </form> <div id="todos"> <br> <br> </div> <script src="todo.js"></script> </div>
方案2:修改JS代码(保留原HTML结构)
如果你想让表单留在#todos里,那就要修改renderNotes,不要清空整个容器,只删除我们自己生成的todo元素,保留表单。可以给生成的元素加个类名,精准删除:
const renderNotes = function(toDo, filters) { const filteredToDo = toDo.filter(function(toDos) { return toDos.task.toLowerCase().includes(filters.searchText.toLowerCase()) }) const todosContainer = document.querySelector('#todos'); // 只删除之前生成的todo相关元素(保留表单) document.querySelectorAll('.todo-item').forEach(item => item.remove()); const existingSummary = todosContainer.querySelector('.todo-summary'); if (existingSummary) existingSummary.remove(); const remaining = filteredToDo.filter(todos => todos.status === 'Uncompleted'); console.log(remaining.length); const summary = document.createElement('h2') summary.className = 'todo-summary'; // 给summary加类名 summary.textContent = `You have ${remaining.length} tasks that are uncompleted`; todosContainer.appendChild(summary) filteredToDo.forEach(function(toDos) { const p = document.createElement('p') p.className = 'todo-item'; // 给每个todo项加类名 p.textContent = toDos.task todosContainer.appendChild(p) }) }
这样不管表单在不在#todos里,都不会被误删,同时todo列表的更新也能正常工作。
内容的提问来源于stack exchange,提问作者Fatal_TC
相关产品推荐
相关产品推荐

