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

时间:2018-12-24 03:22:48

标签: javascript

我正在构建一个待办事项列表项目,并且被困在遍历新创建的列表项中。

这就是我在做什么:

  1. 创建了一个数组。
  2. 通过循环为数组的每个元素制作li项,以便数组以列表方式显示。
  3. 然后遍历新创建的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;
        }
    })
}

5 个答案:

答案 0 :(得分:0)

似乎您只有一个完成的变量与待办事项列表上的每个项目共享。因此,如果您单击其中一项,则所有项目都将被划掉。对于待办事项列表中的每个项目,您将需要一个布尔变量。

答案 1 :(得分:0)

您的代码基本上是正确的,但是有一些问题需要解决。首先,考虑将循环替换为基于for的迭代,如下所示。以这种方式使用forEach()可让您利用"closure",在这种情况下将大大简化您的代码。例如,您可以使用闭包功能将列表中每个项目的forEach()状态存储,而不是将状态显式存储在数组中。

我注意到的另一个问题是done在向文档中添加var list = document.querySelectorAll("li");元素之前先查询文档中的li元素-稍后在脚本中,您似乎正在迭代该空查询结果并期望它能够包含添加的li元素。

这是一个有效的代码段-希望对您有所帮助!

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>

答案 2 :(得分:0)

将此行添加到第二个for循环的上方,并从顶部删除

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

您要在创建值之前就为其分配列表。

答案 3 :(得分:0)

从源代码中,我看到列表li项目在创建新li项目之前已初始化,
这会导致列表项li不包含新项
由于该addEventListener不适用于新项目。

要解决此问题,只需在创建部分之后移动init列表项项即可:

    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;
            }
        })
    }

答案 4 :(得分:0)

请简单点...

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>