为什么用javascript删除元素会阻止元素的迭代
Why does removing an element with javascript prevent iteration of elements?
我正在尝试用标签替换页面上的所有文本字段。
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
,它是live。(对于其他getElementsByXYZ
方法来说是这样,但对于querySelectorAll
则不然。)这意味着,如果移除索引0
处的元素,则HTMLCollection
的长度将减小,并且索引0
处将有一个新元素,而不是刚刚移除的元素。
只要你反向努力,你就会没事的:
for(var i = inputFields.length - 1; i >= 0; i--) {
// ...
}
或者,将HTMLCollection
转换为数组,然后在数组中循环。(请参阅下面的实际示例和代码)。
编辑:或者,正如Chris Shouts在评论中指出的那样,你可以利用不断变化的length
,但这并不像Chris的建议那么简单,因为你有时只是删除元素。它看起来是这样的:
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
实时复制
相关文章:
- 如何使用jquery迭代具有相同属性的html元素并查找onclick事件
- 为什么这只是迭代 HTMLCollection 的奇怪元素
- 每个$.,循环获胜't逐个迭代HTML元素
- 在JSON数组中进行迭代,并为其元素设置样式
- 使用.ech()迭代具有类似类名的元素
- 自动完成搜索无法正常工作,请不要迭代$中的所有元素.每个ul-li都会及时显示响应
- 迭代 coffeescript 中的 jQuery DOM 元素: $(@).捷径
- 如何迭代具有相同ID的元素
- DOM:如何根据迭代器值设置元素宽度并在mouseover上调用函数
- 在JS对象元素上迭代并更改它们
- 迭代JSON对象并将元素打印到屏幕上的最佳方式是什么
- 如何访问迭代模板中的任何元素
- javascript通过逻辑连接的元素对进行迭代
- 使用for.of迭代时删除集合中的元素是否安全
- 如何在数据数组的每次迭代中创建一个内容为“i+1”的新 HTML 元素
- JQuery 添加表单元素迭代 ID
- 每个,从开始元素迭代
- 无法使用守夜人中的元素迭代元素
- Javascript中的表单元素迭代
- jQuery 从子元素迭代内部子元素