我有一个可以由用户折叠或展开的树状列表
<ul>
<li class="exp">
...
</li>
<li>
...
</li>
</ul>
此列表延迟加载的内容,因为它可能很大,而且还因为它可以根据用户在页面上执行的其他操作而更改。
延迟加载工作正常,但在删除/添加项目到列表后更新它是一个问题
我现在的做法是这样的:
var old_i = 0,
new_v = [];
new_li.each(function(i, li){
new_v.push(node.dataset.value);
// new li at the end
if(!old_li.get(old_i)){
old_ul.append(li);
return;
}
// existing li
if(li.dataset.value == old_li.get(old_i).dataset.value){
old_i++;
return;
}
// new li before the end
$(li).insertBefore(old_li.get(old_i));
});
// remove non-existing
old_i.each(function(idx, li){
if(new_v.indexOf(li.dataset.value) < 0)
$(li).remove();
});
但是当我删除最后一个之前的 li 时,最后一个会被重复。我认为问题出在 insertBefore 附近,但我不知道是什么原因造成的。
我不知道该怎么做的另一件事是重新排序旧列表以匹配新列表的顺序。
我知道我可以替换列表以使事情变得更容易,但随后我将失去用户展开-折叠状态。不仅仅是状态类,还有内容,因为ajax响应只返回需要更新的内容,即事件li(直接子级)的内容。但是用户可以扩展它的子代或孙代,并且这些内容将随着替换而丢失
最佳答案
我认为重复项的创建如下所示:
如果您的旧列表是:a、b、c、d,而新列表是:a、c、d:
你的循环与 a 配合得很好。
但是,当新列表循环位于 c 时,old_li.get()
返回 b,从而触发 insertBefore
。旧列表现在是 a,c,b,c,d。
接下来,newlist 返回 d,old_li.get()
返回 c(old_i 不递增)。这会触发另一个 insertBefore
。旧列表现在是 a,d,c,b,c,d。
在您的删除回合之后,c 值将被删除,留下 newlist 为 a,d,d,c,c。
作为替代方法,我建议:
var old_v; // array with only value strings from old state
var new_v; // array with only value strings from new state
var updatedLength=0;
old_v.reverse().map((itemVal,i) => {
if (new_v.indexOf(itemVal) != -1) {
// remove item (i) from the old_li in DOM
// loop over old_v in reverse order so we don't mess up count
} else {
UpdatedLength++;
}
}
new_v.map((itemVal, i) => {
if (old_v.indexOf(itemVal) == -1) {
if (i >= updatedLength) {
// append item (i) from the new_li to DOM at the end
} else {
// insert item (i) before item at index updatedLength in DOM
}
updatedLength++;
}
return itemVal;
}
希望这有效!
关于javascript - 更新现有列表以匹配新列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32784118/