Javascript for loop appendChild 不追加所有项目
Javascript for loop appendChild does not append all items
我正在将 class 中的列表元素从一个列表移动到另一个列表,但我的行为非常奇怪。
相关代码在这些函数中找到:
function moveright(){
console.log("things that are selected");
selected=document.getElementsByClassName("Selected");
for (x=0;x<selected.length;x++){
console.log(selected.item(x).innerText);
}
list=document.getElementById("rightlist");
console.log("Moving right");
for (x=0;x<selected.length;x++){
list.appendChild(selected.item(x));
console.log(selected.item(x).innerText);
}
console.log("things that moved right");
for (x=0;x<list.childElementCount;x++){
console.log(list.children.item(x).innerText);
}
}
function select(ele,eve){
if (!(event.shiftKey)){
selected=document.getElementsByClassName("Selected");
for (x=0;x<selected.length;x++){
selected[x].className=selected[x].className.replace(" Selected","");
}
}
if (ele.className.indexOf(" Selected") == -1) {
ele.className=ele.className+" Selected";
}
}
测试元素示例:
<li style="user-select:none" onclick="select(this)" path="./this/is/a/path" class="pft-file ext-txt Selected">test2.txt</li>
rightlist 和 leftlist 只是 <ul>
个元素。当我 select 三个项目并执行控制台输出的 moveright 函数时,这与屏幕上发生的情况相对应:
things that are selected
test1.txt
test2.txt
test3.txt
Moving right
test2.txt
test1.txt
test3.txt
things that moved right
test1.txt
test3.txt
当我用 2 个元素做同样的实验时,它仍然留下一个。当我第二次调用该函数时,最后一个元素移至右列表。当我调用一个相同的函数将元素从右列表移动到左列表时,它工作正常。我在这方面束手无策。
编辑
所以关于发生了什么的一点线索,当我把列表变长时,它会留下所有其他项目,所以 1、3、5 位置的任何项目都被留下,而 0、2、4 位置是拍摄...
您的问题是 document.getElementsByClassName
returns 一个 "live list",这意味着根据您对 [=26= 所做的更改,元素可以从列表中消失并出现在列表中].
例如,如果您使用 class 名称 "foo"
select,然后从 selected 的元素之一中删除 class,则元素从列表中删除。如果将 "foo"
class 添加到某个元素,该元素将添加到列表中。从集合中的 DOM 中删除整个元素也是如此。
所以做这样的突变会产生意想不到的效果,尤其是在循环中。这基本上与在迭代数组时改变数组结构的问题相同。
作为修复,使用 .querySelectorAll
到 select 元素。 returns 是一个静态元素列表,不会受到 DOM 中更改的影响。元素本身当然会看到自己的变化,但元素列表不会改变。
我正在将 class 中的列表元素从一个列表移动到另一个列表,但我的行为非常奇怪。
相关代码在这些函数中找到:
function moveright(){
console.log("things that are selected");
selected=document.getElementsByClassName("Selected");
for (x=0;x<selected.length;x++){
console.log(selected.item(x).innerText);
}
list=document.getElementById("rightlist");
console.log("Moving right");
for (x=0;x<selected.length;x++){
list.appendChild(selected.item(x));
console.log(selected.item(x).innerText);
}
console.log("things that moved right");
for (x=0;x<list.childElementCount;x++){
console.log(list.children.item(x).innerText);
}
}
function select(ele,eve){
if (!(event.shiftKey)){
selected=document.getElementsByClassName("Selected");
for (x=0;x<selected.length;x++){
selected[x].className=selected[x].className.replace(" Selected","");
}
}
if (ele.className.indexOf(" Selected") == -1) {
ele.className=ele.className+" Selected";
}
}
测试元素示例:
<li style="user-select:none" onclick="select(this)" path="./this/is/a/path" class="pft-file ext-txt Selected">test2.txt</li>
rightlist 和 leftlist 只是 <ul>
个元素。当我 select 三个项目并执行控制台输出的 moveright 函数时,这与屏幕上发生的情况相对应:
things that are selected
test1.txt
test2.txt
test3.txt
Moving right
test2.txt
test1.txt
test3.txt
things that moved right
test1.txt
test3.txt
当我用 2 个元素做同样的实验时,它仍然留下一个。当我第二次调用该函数时,最后一个元素移至右列表。当我调用一个相同的函数将元素从右列表移动到左列表时,它工作正常。我在这方面束手无策。
编辑 所以关于发生了什么的一点线索,当我把列表变长时,它会留下所有其他项目,所以 1、3、5 位置的任何项目都被留下,而 0、2、4 位置是拍摄...
您的问题是 document.getElementsByClassName
returns 一个 "live list",这意味着根据您对 [=26= 所做的更改,元素可以从列表中消失并出现在列表中].
例如,如果您使用 class 名称 "foo"
select,然后从 selected 的元素之一中删除 class,则元素从列表中删除。如果将 "foo"
class 添加到某个元素,该元素将添加到列表中。从集合中的 DOM 中删除整个元素也是如此。
所以做这样的突变会产生意想不到的效果,尤其是在循环中。这基本上与在迭代数组时改变数组结构的问题相同。
作为修复,使用 .querySelectorAll
到 select 元素。 returns 是一个静态元素列表,不会受到 DOM 中更改的影响。元素本身当然会看到自己的变化,但元素列表不会改变。