简体   繁体   中英

Traversing the DOM children of children

why children of a children of an element doesn't return me the the element, instead gives me undefined?

 let val; const list = document.querySelector('.collection'); const listItems = document.querySelector('.collection-item'); val = list.children; val = val[3].children.children; console.log(val);
 <ul class="collection"> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> </ul>

So, the children return HTMLCollection then you have to attach index when getting new children:

 let val; const list = document.querySelector('.collection'); const listItems = document.querySelector('.collection-item'); val = list.children; val = val[2].children[0].children; console.log(val);
 <ul class="collection"> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> <li class="collection-item"> <a class="secondary-content" href="#"> <i class="fa fa-remove"></i> </a> </li> </ul>

document.querySelector('.collection') is a method that returns an HTMLElement object matching any elements containing the "collection" CSS class ( documentation ).

val = list.children is a property and will return an HTMLCollection (an ordered collection, ie. a list ) of any children of the list node.
Being that it the children property returns a list, you can access the individual nodes in the collection by using either the item() method on the collection, or by using array-style notation. See ParentNode.children (MDN) .

Lastly; with the val[3] call, remember that JS array iterations start at 0. To get the third item in the val list/array, you'd use val[2] .

.children is an HTMLCollection , which works like an Array. As such, it doesn't have a .children parameter.

You need to loop through the array or select an item:

val = list.children[0].children

or

list.children.forEach(child => console.log(child.children))

A NodeList / HTML Collection returned from the .children property comprises of the parentElement direct descendants (ie children -- not children of children ). If you want to use .children to get to the "grandchildren" you'll need to iterate through both .children collections or if you have a childElement in mind then bracket notation would be effective (ex. parentElement.children[1] ) BTW the index number in bracket notation is 0-index based so for example .children[2] is actually the third element and so on.

Demo

 // Reference the <ul> const list = document.querySelector('.list'); /* Collect each <li> in <ul> into a NodeListr then convert it into a real Array with the bracket and spread operator (ie [...NodeList] */// itemsA and itemsB are identical const itemsA = [...list.querySelectorAll('.item')]; const itemsB = [...list.children]; /* Since the OP objective was vague...the following are console logs that verify the results. The last console log is my best guess as to what the OP's objective was. */ console.log(` .list direct descendants (aka children):\\n ${itemsB.map(item => ` <${item.tagName.toLowerCase()} class="${item.className}">...<\\/${item.tagName.toLowerCase()}>\\n`)}`); console.log(`Array itemsA (as htmlString):\\n ${itemsA.map(item => item.outerHTML)}`); console.log(`Array itemsB (as htmlString):\\n ${itemsB.map(item => item.outerHTML)}`); console.log(`Third .item of .list (as htmlString):\\n ${itemsA[2].outerHTML}`); console.log(`Third .item of .list deepest descendant:\\n ${[...itemsB[2].children].flatMap((node, index) => node.children[index].outerHTML)}`);
 .list { list-style: none } .item { margin-bottom: 14px } .as-console-wrapper { width: 375px; min-height: 100%; margin-left: 25%; } .as-console-row { border-bottom: 5px ridge #333 } .as-console-row-code::first-line { text-decoration: underline; } .as-console-row.as-console-row::after, .as-console-row-code.as-console-row-code::after { content:''; padding:0; margin:0; border:0; width:0; }
 <link href="https://use.fontawesome.com/releases/v5.12.1/css/all.css" rel="stylesheet" crossorigin="anonymous"> <ul class="list"> <li class="item"> <a class="link" href="#/"> ITEM 1 <i class="fas fa-minus-square"></i> </a> </li> <li class="item"> <a class="link" href="#/"> ITEM 2 <i class="fas fa-minus-square"></i> </a> </li> <li class="item"> <a class="link" href="#/"> ITEM 3 <i class="fas fa-minus-square"></i> </a> </li> </ul>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM