使用 divs.Only JS 动态删除列表
Delete dynamically a list with divs.Only JS
当我选中所有复选框并按下按钮时,始终存在最后一个节点。
我知道这是因为 parentNode 并且因为 DOM 树上的索引仍在内存中或类似的东西中。
某人可以帮助我了解该怎么做吗,我将不胜感激。
function deleteChecked() {
var node_listFields = document.getElementsByClassName('fields');
var checkboxes = document.getElementsByClassName("check");
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
node_listFields[i].parentNode.removeChild(node_listFields[i]);
}
}
}
<input type="button" value="Delete" onclick="deleteChecked()" />
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Θέρμανση
<input type="text" />
<br></br></div>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα
<input type="text" />
<br></br></div>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
<input type="text" />
<br></br></div>
<hr/>
?
那是因为 getElementsByClassName
返回的 HTMLCollection
对象是活动的,这意味着当您删除其中的一个节点时,它会自动更新(因此,您的 i
现在指向一个错误的项目),即在一次删除后导致错误,这就是为什么只有一个项目被删除的原因。
正确的方法是转换成数组(或使用 document.querySelectorAll()
,returns 一个非活动列表)
function deleteChecked() {
var node_listFields = document.getElementsByClassName('fields');
// This converts to an array.
var nodeArray = [].slice.call(node_listFields);
var onlyCheckedArray = nodeArray.filter(function findIfCheckboxIsChecked(node) {
// Returns if the checkbox inside this node is checked.
return node.querySelector('.check').checked;
})
// Here onlyCheckedArray is an array with nodes with only checked checkboxes.
// So let's remove them all!
onlyCheckedArray.forEach(function removeNode(node) {
node.parentNode.removeChild(node);
});
}
<input type="button" onclick="deleteChecked()" />
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Θέρμανση
<input type="text" />
</div>
<br></br>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα
<input type="text" />
</div>
<br></br>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
<input type="text" />
</div>
<br></br>
<hr/>
然后 jsFiddle
我遇到了同样的问题,并使用回归迭代解决了它。
据我了解,DOM 节点索引始终必须固定:0,1,2,3...:[=40=]
渐进迭代(i=0; i<3; i++){
- i = 0 :
checkbox[0]
已删除;
checkbox[1]
成为新的 checkbox[0]
因为 DOM 节点索引总是以 0
;
- i = 1 :
checkbox[1]
被删除,checkbox[0]
留在 DOM (跳过 1 个节点) ;
checkbox[2]
变新checkbox[1]
;
- i = 2 :
checkbox[2]
被删除,checkbox[0]
& [1]
停留在 DOM(跳过 2 个节点);
node[3]
变新node[2]
;
- 结束循环
};
2 个跳过的复选框。需要重复循环直到剩下不到 2 个框,因为每次都会跳过其他框。
var inputElems = document.getElementsByTagName("input");
for(var i = 0; i<inputElems.length; i++){
if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
inputElems[i].parentNode.remove();
}
}
回归迭代(i=2; i>=0; i--){
- i = 2 :
checkbox[2]
已删除(索引中的最后一个复选框);
node[3]
(不是复选框)成为新的node[2]
;
- i = 1 :
checkbox[1]
已删除,(更新索引中的最后一个复选框);
node[2]
(不是复选框)成为新的node[1]
;
- i = 0 :
checkbox[0]
已删除,(更新索引中的最后一个复选框);
node[1]
(不是复选框)成为新的node[0]
(没有更多的复选框!);
- 结束循环
};
跳过的复选框:0。
var inputElems = document.getElementsByTagName("input");
for(var i = inputElems.length-1; i>= 0; i--){
if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
inputElems[i].parentNode.remove();
}
}
当我选中所有复选框并按下按钮时,始终存在最后一个节点。
我知道这是因为 parentNode 并且因为 DOM 树上的索引仍在内存中或类似的东西中。
某人可以帮助我了解该怎么做吗,我将不胜感激。
function deleteChecked() {
var node_listFields = document.getElementsByClassName('fields');
var checkboxes = document.getElementsByClassName("check");
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
node_listFields[i].parentNode.removeChild(node_listFields[i]);
}
}
}
<input type="button" value="Delete" onclick="deleteChecked()" />
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Θέρμανση
<input type="text" />
<br></br></div>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα
<input type="text" />
<br></br></div>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
<input type="text" />
<br></br></div>
<hr/>
?
那是因为 getElementsByClassName
返回的 HTMLCollection
对象是活动的,这意味着当您删除其中的一个节点时,它会自动更新(因此,您的 i
现在指向一个错误的项目),即在一次删除后导致错误,这就是为什么只有一个项目被删除的原因。
正确的方法是转换成数组(或使用 document.querySelectorAll()
,returns 一个非活动列表)
function deleteChecked() {
var node_listFields = document.getElementsByClassName('fields');
// This converts to an array.
var nodeArray = [].slice.call(node_listFields);
var onlyCheckedArray = nodeArray.filter(function findIfCheckboxIsChecked(node) {
// Returns if the checkbox inside this node is checked.
return node.querySelector('.check').checked;
})
// Here onlyCheckedArray is an array with nodes with only checked checkboxes.
// So let's remove them all!
onlyCheckedArray.forEach(function removeNode(node) {
node.parentNode.removeChild(node);
});
}
<input type="button" onclick="deleteChecked()" />
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Θέρμανση
<input type="text" />
</div>
<br></br>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα
<input type="text" />
</div>
<br></br>
<div class="fields">
<input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
<input type="text" />
</div>
<br></br>
<hr/>
然后 jsFiddle
我遇到了同样的问题,并使用回归迭代解决了它。
据我了解,DOM 节点索引始终必须固定:0,1,2,3...:[=40=]
渐进迭代(i=0; i<3; i++){
- i = 0 :
checkbox[0]
已删除;checkbox[1]
成为新的checkbox[0]
因为 DOM 节点索引总是以0
;
- i = 1 :
checkbox[1]
被删除,checkbox[0]
留在 DOM (跳过 1 个节点) ;checkbox[2]
变新checkbox[1]
;
- i = 2 :
checkbox[2]
被删除,checkbox[0]
&[1]
停留在 DOM(跳过 2 个节点);node[3]
变新node[2]
;
- 结束循环
};
2 个跳过的复选框。需要重复循环直到剩下不到 2 个框,因为每次都会跳过其他框。
var inputElems = document.getElementsByTagName("input");
for(var i = 0; i<inputElems.length; i++){
if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
inputElems[i].parentNode.remove();
}
}
回归迭代(i=2; i>=0; i--){
- i = 2 :
checkbox[2]
已删除(索引中的最后一个复选框);node[3]
(不是复选框)成为新的node[2]
;
- i = 1 :
checkbox[1]
已删除,(更新索引中的最后一个复选框);node[2]
(不是复选框)成为新的node[1]
;
- i = 0 :
checkbox[0]
已删除,(更新索引中的最后一个复选框);node[1]
(不是复选框)成为新的node[0]
(没有更多的复选框!);
- 结束循环
};
跳过的复选框:0。
var inputElems = document.getElementsByTagName("input");
for(var i = inputElems.length-1; i>= 0; i--){
if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
inputElems[i].parentNode.remove();
}
}