While traversing the DOM there are sometimes many child elements under one parent.
I can get these children as either node-lists using a querySelectorAll
or I can get them as HTML-Collections by using element.children
.
But when I select one to use to put in my DOM tree traversal I get undefined
.
I have tried turning the node-lists and HTML-Collections into arrays and using them that way with no success. I have tried using for-of loops regular for loops and foreach loops for selecting a single element, yet always with failure undefined
.
I have created a made up situation that shows this situation, although the problem is solvable without having to Traverse the DOM, you have to image that it is necessary.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Testing</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="eric_meyer_reset_2.css" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="wrapper">
<div id="topOfPage">
<header>
<h1>Random Number Generator</h1>
</header>
<div id="simulated RNG">
<p>Your number is: <span id="theRandomNumber">2</span></p>
<button type="button" id="prizeOpenButton">Press for Prize</button>
</div>
</div>
<div id="bottomOfPage">
<!-- These sections are added dynamically during the script operation -->
<section class="joy" data-id="0">Hurray</section>
<section class="joy" data-id="1">Hurrah</section>
<section class="joy" data-id="2">Yay</section>
<section class="joy" data-id="3">Congrats</section>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
.joy {
display: none
}
const randomNumber = document.getElementById("theRandomNumber");
const prizeButton = document.getElementById("prizeOpenButton")
let matchNumberToPrizeSection = function (event) {
let prizeSections = document.querySelectorAll(".joy");
let theSection = null;
for (let i = 0; i < prizeSections.length; i++) {
if (prizeSections[i].dataset.id === randomNumber) {
theSection = prizeSections[i];
}
}
// lets say for some reason we have to traverse the DOM
// starting with the button going to the "theSection" above
let winningSection = event.target.parentElement.parentElement.nextElementSibling.theSection;
console.log(winningSection.innerHTML);
}
prizeButton.addEventListener("click", matchNumberToPrizeSection);
While you cannot use node-list or HTML-Collection elements directly or indirectly when you are building up a DOM traversal. What I finally found was that I can use the element before the many child elements, in my original question that was a div
with id of bottomOfPage. What I had to do was find the index of the child element that I needed using the node-list elements and use that index in the parent div
like this. event.target.parentElement.parentElement.nextElementSibling.children(index)