我正在尝试用标签替换页面上的所有文本字段。
function replaceInputTextFieldsWithValues() {
var inputFields = document.getElementsByTagName("input");
for(var i = 0; i < inputFields.length; i++) {
if(inputFields[i].getAttribute("type")== "text") {
var parent = inputFields[i].parentNode;
var value = inputFields[i].value;
parent.removeChild(inputFields[i]);
var label = document.createElement('label');
label.setAttribute('for', value);
label.innerHTML = value;
parent.appendChild(label);
}
}
}
我的 HTML 文档是按表格组织的。此函数似乎仅适用于每个表中的第一个元素。
另一方面,当我删除该行时:
parent.removeChild(inputFields[i]);
该代码似乎工作正常。为什么会发生这种情况以及如何解决它?
最佳答案
从 getElementsByTagName
返回的是 HTMLCollection
,这是实时。 (这对于其他 getElementsByXYZ
方法是正确的,但对于 querySelectorAll
则不然。)这意味着如果您删除索引 0
处的元素, >HTMLCollection
的长度将会减小,并且您将在索引 0
处看到一个新元素,而不是刚刚删除的元素。
只要向后看就可以了:
for(var i = inputFields.length - 1; i >= 0; i--) {
// ...
}
或者,将 HTMLCollection
转换为数组,然后循环访问该数组。 (请参阅下面的实例和代码)。
编辑:或者,正如 Chris Shouts 在评论中指出的那样,您可以仅利用不断变化的长度
,但事实并非如此相当就像克里斯的建议一样简单,因为您只是有时删除元素。它看起来像这样:
var inputFields = document.getElementsByTagName("input");
var i = 0;
while (i < inputFields.length) {
if(inputFields[i].getAttribute("type")== "text") {
// Remove it and DON'T increment `index`
}
else {
// Skip this one by incrementing `index`
++index;
}
}
使用这三种方法中的哪一种取决于具体情况。复制到数组可以为您提供一个很好的静态数据集来使用,如果您确保释放对 HTMLCollection
的引用,您就让浏览器有机会意识到它不必这样做当情况发生变化时保持该列表最新,这可以减少开销。但是您只是简单地复制引用,这会增加一点开销。 :-)
附加:下面的示例展示了这种效果,还展示了从 HTMLCollection
创建数组的相当有效(但晦涩)的方法:
HTML:
<ul>
<li>LI0</li>
<li>LI1</li>
<li>LI2</li>
</ul>
JavaScript:
var lilist, liarray;
// Get the HTMLCollection, which is live
lilist = document.getElementsByTagName('li');
// Create an array of its elements
liarray = Array.prototype.slice.call(lilist, 0);
// Show initial length of both
display("lilist.length = " + lilist.length); // Shows 3
display("liarray.length = " + liarray.length); // Shows 3
// Show what the 0th element of both is (both show "LI0" in the live example)
display("lilist[0].innerHTML = " + lilist[0].innerHTML); // Shows LI0
display("liarray[0].innerHTML = " + liarray[0].innerHTML); // Shows LI0
// Remove the first list item
display("Removing item 0");
lilist[0].parentNode.removeChild(lilist[0]);
// Show the length of both, note that the list's length
// has gone down, but the array's hasn't
display("lilist.length = " + lilist.length); // Shows 2, not 3
display("liarray.length = " + liarray.length); // Still shows 3
// Show what the 0th element of both *now* is
display("lilist[0].innerHTML = " + lilist[0].innerHTML); // Shows LI1 now
display("liarray[0].innerHTML = " + liarray[0].innerHTML); // Still shows LI0
关于javascript - 为什么使用 javascript 删除元素会阻止元素迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6140146/