我正在将一个类中的列表元素从一个列表移动到另一个列表,但我的行为非常奇怪。
相关守则可在以下功能中找到:
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>
权利列表和左列表只是<ul>
个元素。当我选择三个项目并执行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个位置是采取...
答案 0 :(得分:1)
您的问题是document.getElementsByClassName
会返回&#34;实时列表&#34;,这意味着元素可以从列表中消失,并根据您对DOM所做的更改显示在其中。
例如,如果您按类名"foo"
选择,但随后从所选元素之一中删除该类,则该元素将从列表中删除。如果将"foo"
类添加到元素,则该元素将添加到列表中。从集合中的DOM中删除整个元素也是如此。
所以做这样的突变会产生惊人的效果,尤其是在循环中。当你重复迭代数组的结构时,它基本上是同样的问题。
作为修复,请使用.querySelectorAll
选择元素。这将返回一个静态的元素列表,这些元素不受DOM中的更改的影响。元素本身会看到自己的变化,但元素列表不会发生变化。