如何循环遍历 javascript 中的子对象?

我在一个函数中有这样的代码:

tableFields = tableFields.children;
for (item in tableFields) {
// Do stuff
}

根据 tableFields 的 console.log,我正在返回一个数组,因为我认为我需要这样做。循环中的一个 console.log 条目返回未定义的。要遍历 tableFields 并将每个对象插入到表中,我需要做什么?

TableFields 的控制台日志:

HTMLCollection[label, input, label, input 25, label, input, input, input Remove]




0
label


1
input


2
label


3
input 25


4
label


5
input


6
input


7
input Remove


description[]
input


hours[]
input


invoice_number
input


getlength
8


rate[]
input 25


item
item()


iterator
iterator()


namedItem
namedItem()


__proto__
HTMLCollectionPrototype { item=item(), namedItem=namedItem(), iterator=iterator()}

下面是到目前为止我所看到的代码的整个部分:

$this->title("Test");
$this->defaultMenu();
$select = "";
$names = Customer::getNames();
foreach ($names as $id => $name) {
$select .= '<option value="'.$id.'"';
if ($this->customerid == $id) $select .= ' selected ';
$select .= '>'.$name.'</option>';
}


$form = '
<script type="text/javascript">


var counter = 0;


function isEven(int){
int = Number(int);
return (int%2 == 0);
}






function moreLabor() {


var table = document.getElementById("editTable");
var tableFields = document.getElementById("readroot");


tableFields = tableFields.children;
console.log(tableFields);
for (item in tableFields) {


if (isEven(counter)) {
var tableRow = table.insertRow(-1);
var label = tableRow.insertCell(-1);
console.log(tableFields[item]);
label.appendChild(tableFields[item]);


} else {
var field = tableRow.insertCell(-1);
field.innerHTML = item.innerHTML;




}


counter++;
}


console.log();
var insertHere = document.getElementById("writeroot");
}


window.onload = function(){
document.getElementById(\'moreLabor\').onclick = function(){ moreLabor(); }
moreLabor();
}




</script>


<div id="readroot" style="display: none">
<tr>
<td><label for="hours">Hours:</label></td>
<td><input type="text" name="hours[]" value="" /></td>
</tr>
<tr>
<td><label for="rate">Rate:</label></td>
<td><input type="text" name="rate[]" value="25" /></td>
</tr>
<tr>
<td><label for="description">Description:</label></td>
<td><input type="text" name="description[]" value="" /></td>
</tr>


<input type="hidden" name="invoice_number" value="'.$this->number.'" />
<tr>
<td><input type="button" value="Remove"
onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /></td>
</tr>


</div>


<form method="POST" class="invoice" id="edit">
<table id="editTable">
<tr>
<td><label>Work Order Number:</label></td>
<td><input type="text" name="number" value="'.$this->number.'"/></td>
</tr>
<tr>
<td><label>Customer:</label></td>
<td><select name="customerid">'.$select.'</select></td>
</tr>
<span id="writeroot"></span>


<tr>
<td><input type="button" id="moreLabor" value="Add labor"/></td>
<td><input type="submit" name="Save" value="Save" /></td>
</tr>';
if (!is_null($this->id)) {
$form .= '<input type="hidden" name="id" value="'.$this->id.'"/>';
}
$form .= '</table></form>';






$this->component($form);
163391 次浏览

诀窍在于,DOM Element.children属性不是一个数组,而是一个 类似数组的集合,它有长度,可以像数组一样进行索引,但它不是一个数组:

var children = tableFields.children;
for (var i = 0; i < children.length; i++) {
var tableChild = children[i];
// Do stuff
}

顺便说一下,通常使用基本 for 循环而不是 for-in 循环迭代数组是更好的做法。

如果 tableFields是一个数组,则可以循环遍历以下元素:

for (item in tableFields); {
console.log(tableFields[item]);
}

顺便说一下,我在你的代码中看到了一个逻辑错误。只要从 for 循环的末尾删除 ;

就在这里:

for (item in tableFields); {.

这将导致您的 r 循环什么也不做。下面的代码行将只执行一次:

// Do stuff

向后兼容的版本(IE9 +)是

var parent = document.querySelector(selector);
Array.prototype.forEach.call(parent.children, function(child, index){
// Do stuff
});

ES6的方式是

const parent = document.querySelector(selector);
Array.from(parent.children).forEach((child, index) => {
// Do stuff
});

ECS6中,可以使用 数组来自()传播数组语法:

const listItems = document.querySelector('ul').children;
const listArray = Array.from(listItems);
// or
const listArray = [...listItems];
listArray.forEach((item) => {console.log(item)});

我很惊讶没人用这个密码回答:

for(var child=elt.firstChild;
child;
child=child.nextSibling){
do_thing(child);
}

或者,如果你只想要子元素, 这个代码:

for(var child=elt.firstElementChild;
child;
child=child.nextElementSibling){
do_thing(child);
}

在2020/2021年,使用 Array.from将类似数组的节点“转换”为实际的数组,然后使用 .map循环遍历所得到的数组更加容易。 代码简单如下:

Array.from(tableFields.children).map((child)=>console.log(child))

现代 JS 还使用 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statments/for.of”rel = “ noReferrer”> for. . of 使我们能够迭代 DOM 子对象、数组或其他可迭代对象。我认为这是非常干净和简单的。

var children = tableFields.children;
for (c of children) {
console.log(c);
// Do stuff with child c
}

用 ES6,

[...element.children].map(child => console.log(child));