【问题标题】:How do I loop through children objects in javascript?如何在 javascript 中遍历子对象?
【发布时间】:2013-06-13 18:18:39
【问题描述】:

我在函数中有这段代码:

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);

【问题讨论】:

    标签: javascript


    【解决方案1】:

    诀窍在于the DOM Element.children attribute 不是一个数组,而是一个类数组集合,它有长度并且可以像数组一样被索引,但它不是一个数组:

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

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

    【讨论】:

    • 那么如何获取父元素的内部元素呢?
    • @CoreyRay:在我的示例代码中,“tableFields”是父元素,“children”是子元素。
    • 我发现这个工作正常:for(let x of Array.from(tableFields.children)) {...}
    • 这只查看tableFields的直接子节点;您想使用 getElementsByTagName('*') 查看所有子项和嵌套子项。见jsfiddle.net/Abeeee/gd3eokb5/5
    • @RocketNuts 一个 HTMLCollection 提供了处理 html 元素的其他方法,因此它比数组更有用。如上所述,您可以使用 for (ele of collection) ... 遍历项目...
    【解决方案2】:

    ECS6中,可以使用Array.from()Spread array syntax

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

    【讨论】:

    • 奇怪的是,这种方法比第一个答案建议的直接迭代 children 属性要快得多(在 Chrome 中大约是 15 倍)。想知道为什么...
    【解决方案3】:

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

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

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

    就在这里:

    for (item in tableFields); {.

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

    // Do stuff
    

    【讨论】:

    • 谢谢,我做了建议的更改。我正在尝试将这些项目附加到表行对象
    【解决方案4】:

    向后兼容的版本(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
    });
    

    【讨论】:

      【解决方案5】:

      现代 JS 还使用 for..of 使我们能够迭代 DOM 子对象、数组或其他可迭代对象。我认为它非常干净和简单。

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          使用 ES6,

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

          【讨论】:

            【解决方案8】:

            我很惊讶没有人回答这个代码:

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

            或者,如果你只想要作为元素的子元素, 这段代码:

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

            【讨论】:

              猜你喜欢
              • 2021-05-08
              • 2013-01-01
              • 2017-12-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-09-24
              • 2023-03-24
              • 1970-01-01
              相关资源
              最近更新 更多