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 中更改的影响。元素本身当然会看到自己的变化,但元素列表不会改变。