简体   繁体   中英

How do I get this div to show again using JavaScript

I have made a TODO app and added a counter to keep a count of the items in the list. If the counter hits zero, I've set it to re-show a message 'You currently have no tasks. Use the input field above to start adding.'

if(count === 0){
  noTasksText.classList.remove('d-none');
}

In the console I print out the div and it doesn't have d-none in the class list any more which is what I want, however, in the actual DOM it does.

Here is a full example - https://codepen.io/tomdurkin/pen/LYdpXKJ?editors=1111

I really can't seem to work this out. I can't seem to interact with that div when the counter becomes zero, however I can get console logs etc to show when expected.

Any help would be appreciated!

 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>

Upon setting innerHTML by using += innerHTML the node noTasksText is lost, because browser processes the whole new set innerHTML and creates new objects. You can either retrieve noTasksText again after that, or append nodes using todoContainer.appendChild . I forked your pen and solved it with the latter solution.

https://codepen.io/aghosey/pen/wvmGwWd

You can do the following, it will work (here innerHTML is changing the DOM, so I added an extra function to recalculate elements after DOM is changed due to innerHTML):

 var mainInput = document.querySelector("#main-input"); var todoContainer = document.querySelector("#todo-container"); var errorText = document.querySelector("#js-error"); var noTasksText = document.querySelector(".js-no-tasks"); let tasks = []; let count = 0; function getAllElements() { mainInput = document.querySelector("#main-input"); todoContainer = document.querySelector("#todo-container"); errorText = document.querySelector("#js-error"); noTasksText = document.querySelector(".js-no-tasks"); } // focus input on load window.onload = () => { mainInput.focus(); var 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; getAllElements(); }); } 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; getAllElements(); // 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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