I have a question regarding DOM manipulation, say I insert a grid using this function:
const grid__container = document.querySelector('.grid__container'); function createVertexes() { for (let i = 0; i < 9; i++) { const grid = document.createElement("div"); grid.setAttribute('class', "vertex"); grid.setAttribute('id', i+1); grid__container.appendChild(grid); } }
afterwards, I try to grab all the vertexes with the class “vertex” using document.querySelectorAll(“vertex”) it doesnt work:
const vertexes = document.querySelectorAll('.vertex');
console log of this returns:
[]
but this works:
const vertexes = grid__container.childNodes;
console.log of this actually returns all 9 divs
I see that the difference is that grid__container is pre-defined in my HTML file, but I wrote the querySelectorAll method in a top down approach, so I dont understand why query selector doesnt work, because I created the elements then tried to grab it, anyone knows why?
I only know this is called DOM-manipulation and not know the exact name of this error and am quite new to javascript, please help.
I expected the console to log out 9 divs, but my vertexes here using querySelectorAll instead logs out a nodelist of length 0 <NodeList: length 0>
// grab the main container const grid__container = document.querySelector('.grid__container'); const mole = document.querySelector(".mole"); const timeLeft = document.querySelector("#time__left"); const score = document.querySelector("#score"); let result = 0; function createVertexes() { for (let i = 0; i < 9; i++) { const grid = document.createElement("div"); grid.setAttribute('class', "vertex"); grid.setAttribute('id', i + 1); grid__container.appendChild(grid); } } // const vertexes = grid__container.childNodes; const vertexes = document.querySelectorAll('.vertex'); console.log(vertexes); function randomSquare() { vertexes.forEach(vertex => { vertex.classList.remove('mole') console.log(vertex); }) let randomVertex = vertexes[Math.floor(Math.random() * 9)] randomVertex.classList.add('mole'); } createVertexes(); randomSquare();
* { box-sizing: border-box; } .grid__container { width: 600px; height: 600px; display: flex; flex-wrap: wrap; } .vertex { height: 200px; width: 200px; border: solid black 1px; } .mole { background-color: burlywood; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Whac-a-mole</title> <link rel="stylesheet" href="./styles.css"> <script src="./app.js" defer></script> </head> <body> <h2>Your score:</h2> <h2 id="score">Score</h2> <h2>Time left:</h2> <h2 id="time__left">Time left</h2> <div class="grid__container"></div> </body> </html>
Advertisement
Answer
Your code works if you spell everything correctly and run the code AFTER the DOM is complete AND get the vertexes at the time you need them
Also the .mole is not available until after the randomSquare has run
window.addEventListener("DOMContentLoaded", function() { // grab the main container const grid__container = document.querySelector('.grid__container'); const timeLeft = document.querySelector("#time__left"); const score = document.querySelector("#score"); let result = 0; for (let i = 0; i < 9; i++) { const grid = document.createElement("div"); grid.setAttribute('class', "vertex"); grid.setAttribute('id', i + 1); grid__container.appendChild(grid); } function randomSquare() { const vertexes = document.querySelectorAll('.vertex'); vertexes.forEach(vertex => { vertex.classList.remove('mole') }) let randomVertex = vertexes[Math.floor(Math.random() * 9)] randomVertex.classList.add('mole'); } randomSquare(); // const mole = document.querySelector(".mole"); })
* { box-sizing: border-box; } .grid__container { width: 600px; height: 600px; display: flex; flex-wrap: wrap; } .vertex { height: 200px; width: 200px; border: solid black 1px; } .mole { background-color: burlywood; }
<h2>Your score:</h2> <h2 id="score">Score</h2> <h2>Time left:</h2> <h2 id="time__left">Time left</h2> <div class="grid__container"></div>