简体   繁体   English

js遍历新创建的列表元素的问题

[英]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. 通过循环为数组的每个元素设置li个项,以便数组以列表方式出现。
  3. And then looping through newly created li section to addEventListener on each of li's ( But this one is not working). 然后循环遍历新创建的li节,以在li的每个li上添加addEventListener(但此方法不起作用)。

 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. 首先,考虑使用基于forEach()迭代替换您的for循环,如下所示。 Using forEach() in this way allows you to leverage "closure" which in this case will greatly simplify your code. 通过这种方式使用forEach() ,您可以利用“关闭”功能 ,在这种情况下,可以大大简化您的代码。 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. 例如,您可以使用闭包功能将每个项目的done状态存储在列表中,而不是将状态显式存储在数组中。

The other issue I noticed was var list = document.querySelectorAll("li"); 我注意到的另一个问题是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. 在将任何li元素添加到文档之前,先查询文档中的li元素-稍后在脚本中,您似乎正在迭代该空查询结果,并期望它包含添加的li元素。

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 . 在第二个for循环的上方添加此行,并从顶部删除

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, 从源代码中,我看到列表li项目在创建新li项目之前已初始化,
it will cause the list li item not contains the new one, 这将导致列表li项目不包含新项目,
due to that addEventListener will not working for the new item. 由于addEventListener不适用于新项目。

to fix this, just need move init list li item code after creation part : 为了解决这个问题,只需要在创建part之后移动init list li项目代码即可:

    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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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