简体   繁体   中英

Problem with Looping through over a newly created list element by js

I am building a Todo-List Project and i am stuck at looping through my newly created list items.

This is what i am doing:

  1. Created an array.
  2. Made li items for array's each element through looping so that array appears in a list manner.
  3. And then looping through newly created li section to addEventListener on each of li's ( But this one is not working).

 var arrList = ["play","learn","walk"];
 var list = document.querySelectorAll("li");
 var done = false;

//printing array in list manner
for(let i = 0; i < arrList.length; i++){
    let el = document.createElement("li")
    el.textContent = arrList[i];
    document.querySelector("ul").appendChild(el);
}
//looping through each li's to apply if else statement
 for(let i = 0; i < list.length; i++){
    list[i].addEventListener("click",function(){
        if(!done){
            this.style.textDecoration = "line-through";
            done = true;
        }else{
            this.style.textDecoration = "none";
            done = false;
        }
    })
}

It seems like you only have one done variable that is shared for every item on the todo list. Therefore if you click one of the items all of the items will be crossed out. You will need a boolean variable for every item in your to do list.

You're code is mostly correct, however there are a few issues that need to be addressed. First, consider replacing your for loop with iteration based on forEach() as shown below. Using forEach() in this way allows you to leverage "closure" which in this case will greatly simplify your code. For instance, you can use the closure feature to store the done state of each item in your list, rather than storing that state explicitly in an array.

The other issue I noticed was var list = document.querySelectorAll("li"); queries the document for li elements before any are added to your document - later in your script it seems you're iterating that empty query result and expecting it to contain the added li elements.

Here's a working snippet - hope this helps!

 var arrList = ["play", "learn", "walk"]; // Iterate the list via forEach arrList.forEach(function(arrItem) { // We're now in a new "closure" for this list item // so we can define some state like "done" that will // be used exclusively for this list item var done = false; // Create li element for this list item as before var el = document.createElement("li") el.textContent = arrItem; // Configure click event el.addEventListener("click", function() { // Notice we're able to use the done variable // in this closure for this list item? The key // thing to understand is that each list item // will have it's own unique "done" variable if (!done) { el.style.textDecoration = "line-through"; done = true; } else { el.style.textDecoration = "none"; done = false; } }) document.querySelector("ul").appendChild(el); }); 
 <ul></ul> 

Add this line just above the second for loop and remove from the top .

var list = document.querySelectorAll("li");

You are assigning list the values even before they are created.

from the source code I see that the list li item is initialized before new li item been created,
it will cause the list li item not contains the new one,
due to that addEventListener will not working for the new item.

to fix this, just need move init list li item code after creation part :

    var arrList = ["play","learn","walk"];
    var done = false;

    //printing array in list manner
    for(let i = 0; i < arrList.length; i++){
        let el = document.createElement("li")
        el.textContent = arrList[i];
        document.querySelector("ul").appendChild(el);
    }

    var list = document.querySelectorAll("li");
    //looping through each li's to apply if else statement
    for(let i = 0; i < list.length; i++){
        list[i].addEventListener("click",function(){
            if(!done){
                this.style.textDecoration = "line-through";
                done = true;
            }else{
               this.style.textDecoration = "none";
               done = false;
            }
        })
    }

Please, be simple...

 var arrList = ["play","learn","walk"], UL_arrList = document.querySelector("ul") ; arrList.forEach (arrItem => { let el = document.createElement("li"); el.textContent = arrItem; UL_arrList.appendChild(el); el.onclick = function(e){ let deco = this.style.textDecoration || 'none'; this.style.textDecoration = (deco==='none') ? 'line-through': 'none'; } }); 
 <ul></ul> 

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