【发布时间】:2022-07-07 23:21:03
【问题描述】:
我制作了一个 TODO 应用程序并添加了一个计数器来记录列表中的项目。如果计数器达到零,我已将其设置为重新显示消息“您当前没有任务。使用上面的输入字段开始添加。'
if(count === 0){
noTasksText.classList.remove('d-none');
}
在控制台中,我打印出 div,它在类列表中不再有 d-none,这是我想要的,但是,在实际的 DOM 中它确实如此。
这是一个完整的例子 - https://codepen.io/tomdurkin/pen/LYdpXKJ?editors=1111
我似乎真的无法解决这个问题。当计数器变为零时,我似乎无法与该 div 交互,但是我可以让控制台日志等在预期时显示。
任何帮助将不胜感激!
const mainInput = document.querySelector('#main-input');
const todoContainer = document.querySelector('#todo-container');
const errorText = document.querySelector('#js-error');
const noTasksText = document.querySelector('.js-no-tasks')
let tasks = [];
let count = 0;
// focus input on load
window.onload = () => {
mainInput.focus();
const storedTasks = JSON.parse(localStorage.getItem('tasks'));
if (storedTasks != null && storedTasks.length > 0) {
// set count to number of pre-existing items
count = storedTasks.length
// hide the 'no tasks' text
noTasksText.classList.add('d-none');
// overwrite tasks array with stored tasks
tasks = storedTasks;
tasks.forEach(task => {
// Build the markup
const markup = `
<div class="js-single-task single-task border-bottom pt-2 pb-2">
<div class="row">
<div class="col d-flex align-items-center js-single-task-name">
<h5 class="mb-0" data-title="${task}">${task}</h5>
</div>
<div class="col d-flex justify-content-end">
<button class="js-remove-task d-block btn btn-danger">Remove Item</button>
</div>
</div>
</div>`;
// Append it to the container
todoContainer.innerHTML += markup;
});
} else {
if (noTasksText.classList.contains('d-none')) {
noTasksText.classList.remove('d-none');
}
}
};
// event listener for 'enter on input'
mainInput.addEventListener("keydown", e => {
// if error is showing, hide it!
if (!errorText.classList.contains('d-none')) {
errorText.classList.add('d-none');
}
if (e.key === "Enter") {
// Get the value of the input
let inputValue = mainInput.value;
if (inputValue) {
// Build the markup
const markup = `
<div class="js-single-task border-bottom pt-2 pb-2">
<div class="row">
<div class="col d-flex align-items-center js-single-task-name">
<h5 class="mb-0" data-title="${inputValue}">${inputValue}</h5>
</div>
<div class="col d-flex justify-content-end">
<button class="js-remove-task d-block btn btn-danger">Remove Item</button>
</div>
</div>
</div>`;
// hide 'no tasks' text
noTasksText.classList.add('d-none');
// Append it to the container
todoContainer.innerHTML += markup;
// Push value to 'tasks' array
tasks.push(inputValue);
// Put in localStorage
textTasks = JSON.stringify(tasks);
localStorage.setItem("tasks", textTasks);
// Reset the value of the input field
mainInput.value = '';
// add 1 to the count
count++
} else {
// Some very basic validation
errorText.classList.remove('d-none');
}
}
});
// remove task
todoContainer.addEventListener('click', (e) => {
// Find the button in the row that needs removing (bubbling)
const buttonIsDelete = e.target.classList.contains('js-remove-task');
if (buttonIsDelete) {
// Remove the HTML from the screen
e.target.closest('.js-single-task').remove();
// Grab the name of the single task
let taskName = e.target.closest('.js-single-task').querySelector('.js-single-task-name h5').getAttribute('data-title');
// filter out the selected word
tasks = tasks.filter(item => item != taskName);
textTasks = JSON.stringify(tasks);
localStorage.setItem("tasks", textTasks);
// update counter
count--
// check if counter is zero and re-show 'no tasks' text if true
if (count === 0) {
noTasksText.classList.remove('d-none');
console.log(noTasksText);
}
}
});
body {
background: #e1e1e1;
}
<div class="container">
<div class="row d-flex justify-content-center mt-5">
<div class="col-10 col-lg-6">
<div class="card p-3">
<h2>To dos</h2>
<p>
Use this app to keep a list of things you need to do
</p>
<input class="form-control" id="main-input" type="text" placeholder="Type your todo and hit enter..." class="w-100" />
<small id="js-error" class="text-danger d-none">
Please type a value and press enter
</small>
<hr />
<h4 class="mb-5">Your 'To dos'</h4>
<div id="todo-container">
<!-- todos append in here -->
<div class="js-no-tasks">
<small class="d-block w-100 text-center mb-3">
<i>
You currently have no tasks. Use the input field above to start adding
</i>
</small>
</div>
</div>
</div>
<!-- /card -->
</div>
</div>
</div>
【问题讨论】:
-
请阅读How to Ask,其中注明。 “如果可以创建一个可以链接到的问题的实时示例(例如,在sqlfiddle.com 或jsbin.com),那么就这样做 - 但也将代码复制到问题本身中。不是每个人都可以访问外部网站,链接可能会随着时间的推移而中断。使用Stack Snippets 进行内联 JavaScript/HTML/CSS 的现场演示。”
-
注意,调用
remove之前不需要检查类是否存在;如果您调用remove并且该类不存在,则不会发生错误。 -
谢谢,我会删除那张支票!
-
我感觉这是因为
querySelector返回了对非活动元素的引用。你可以试试document.querySelector('.js-no-tasks').classList.remove('d-none')看看是否可行。但这似乎不对,这就是我不回答的原因:)。 -
当您使用
innerHTML +=处理DOM 时,您丢失了变量noTasksText的引用。简单的解决方案是在删除按钮处理程序const noTasksText = document.querySelector(".js-no-tasks");中声明变量
标签: javascript