I got this thing over here:
function duplicateElement() {
const holder = document.querySelector('.holder');
let elements = document.querySelectorAll('.item');
let firstEl = elements[0];
//let lastEl = elements[elements.length - 1];
console.log(elements.length);
let dimensions = firstEl.offsetWidth;
let reducedDimensions = dimensions / 1.45;
elements.forEach(element => {
let duplicate = element.cloneNode(true);
holder.appendChild(duplicate);
element.style.width = `${reducedDimensions}px`;
element.style.height = `${reducedDimensions}px`;
});
}
let callCount = 1;
let repeater = setInterval(function() {
if (callCount < 5) {
duplicateElement();
callCount += 1;
} else {
clearInterval(repeater);
}
}, 5000);
.bg-black {
background: black;
}
.item {
border-radius: 50%;
}
.square::after content: "";
display: block;
padding-bottom: 100%;
}
<div class="holder">
<div class="bg-black square item"></div>
</div>
What this does is that it runs the function duplicateElements n times.
In duplicateElements() i double the number of elements in each iteration. The parent starts with just 1 item, which become 2, 4, 8, 16, etc (depending on callCount). This works as i want.
Additionally, i want to reduce the size of every element. So i check for the dimensions of the first item, divide the number by a factor and apply the new dimensions as width and height to every item.
That however does not work, as it applies the new dimensions only to the newly duplicated items, leaving the items created in the previous iteration with their old values. (You can check this in the console, as it applies that values as well)
What i am missing here? My train of thought was that since i check for all items with let elements = document.querySelectorAll('.item') anew in EVERY ITERATION, i would also apply my new dimensions to each element.
console.log(elements.length); gives me the correct number of items in each iteration so why don't the dimensions apply?
Hey, thanks!
The problem is: you select all elements before the loop in
let elements = document.querySelectorAll('.item');
Which is correct, but then inside the loop you duplicate the current element and append it to the DOM before setting the dimensions, so this duplicated element is not getting the new dimensions before beign appended...
So, the solution is: just move the part that duplicate the element to below the part that set the dimensions, see below, inside the loop (I reduced to 1 second to faster example)
function duplicateElement() {
const holder = document.querySelector('.holder');
let elements = document.querySelectorAll('.item');
let firstEl = elements[0];
console.clear()
console.log(elements.length);
let dimensions = firstEl.offsetWidth;
let reducedDimensions = dimensions / 1.45;
elements.forEach(element => {
element.style.width = `${reducedDimensions}px`;
element.style.height = `${reducedDimensions}px`;
let duplicate = element.cloneNode(true);
holder.appendChild(duplicate);
});
}
let callCount = 1;
let repeater = setInterval(function() {
if (callCount < 5) {
duplicateElement();
callCount += 1;
} else {
clearInterval(repeater);
}
}, 1000);
.bg-black {
background: black;
}
.item {
border-radius: 50%;
}
.square::after {
content: "";
display: block;
padding-bottom: 100%;
}
<div class="holder">
<div class="bg-black square item"></div>
</div>
Also, I fixed the CSS, there was missing a {
Related
Hers's question which I need answer
Exercises: Level 1
Question 1
I tried to append the child dynamically and get the result vertical not in the compact manner as you will see in the question output when you go to the link
let hh = document.querySelector('h1')
hh.style.textAlign = 'center'
let hh1 = document.querySelector('h2')
hh1.style.textAlign = 'center'
let hh2 = document.querySelector('h3')
hh2.style.textAlign = 'center'
for (i = 0; i <= 100; i++) {
let p1 = document.createElement('div');
{
if (i % 2 == 0) {
p1.className = 'Container'
p1.style.fontSize = '25px'
p1.style.backgroundColor = '#91E537'
p1.textContent = i;
p1.style.padding = '55px'
p1.style.margin = '1px'
p1.style.textAlign = 'center'
p1.style.width = '20px'
document.body.appendChild(p1);
} else {
p1.className = 'Container'
p1.style.fontSize = '25px'
p1.textContent = i;
p1.style.backgroundColor = '#E5D037'
p1.style.padding = '55px'
p1.style.margin = '1px'
p1.style.textAlign = 'center'
p1.style.width = '20px'
document.body.appendChild(p1);
}
}
if (i >= 2) {
let flag = 0;
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
p1.className = 'Container'
p1.style.fontSize = '25px'
p1.style.backgroundColor = '#E55137'
p1.textContent = i;
p1.style.padding = '55px'
p1.style.margin = '1px'
p1.style.textAlign = 'center'
p1.style.width = '20px'
document.body.appendChild(p1);
}
}
}
<h1>Number Generator</h1>
<h2>30 days of JavaScript</h2>
<h3>Author:ABC</h3>
<div class="container"></div>
You can see the code of both HTML and javascript above!!!
Do help with the code where I can easily append the data, and don't use box elements I need simple code for this.
I tried to do it with a few HTML styles but it didn't help me, also using insert-adjacent text also didn't work.
Try to make changes only on javascript code, not HTML,if it's possible else make minimum changes on HTML
I am using HTML5 AND CSS3
Rather than adding lots of inline style attributes to all the generate elements some simple CSS can be applied to the parent (container) and thus the children and then use Javascript to assign the classes to the elements based upon the given criteria of odd/even & prime. The comments throughout the code ought to help
// helper function to create basic DOM element with attributes
const node=( type='div', attr={} )=>{
let n = document.createElement(type);
Object.keys( attr ).forEach( a=>n.setAttribute( a, attr[a] ) );
return n;
};
// utility to test if a number is a "Prime Number"
const isprime=( n=0 )=>{
for( let i = 2; i < n; i++ ) {
if( n % i === 0 ) return false;
}
return n > 1;
};
// generate between these numbers
const iStart=1;
const iEnd=100;
// HTML container
const results = document.querySelector('#results');
// iterate through number range and add new DIV for each number
for( let i = iStart; i<=iEnd; i++ ) {
// calculate the className to assign
let cn=i % 2 === 0 ? 'even' : 'odd';
if( isprime( i ) ) cn='prime';
// create the DIV
let div=node( 'div', { 'class':cn, 'data-id':i } );
// append to output container
results.appendChild( div );
}
// generate Page headers before results / output
let headers={
h1:'Number Generator',
h2:'30 days of Javascript',
h3:'Geronimo Bogtrotter III'
};
// iterate over the keys/properties of the object and create
// a new header for each using the value assigned within the object.
Object.keys( headers ).forEach( prop=>{
let n=node( prop );
n.textContent=headers[ prop ];
// add the new header before the numbers grid
document.body.insertBefore( n, results );
});
/*
Some simple variables to help with layout.
Change here to modify displayed grid.
*/
:root{
--width:600px;
--m:0.25rem;
--r:0.35rem;
--wh:calc( calc( var( --width ) / 5 ) - calc( var( --m ) * 4 ) );
}
body{
font-family:monospace;
padding:0;
margin:0;
}
#results {
width: var(--width);
min-height: var(--width);
float: none;
margin: 1rem auto;
font-family:fantasy;
}
#results > div {
width: var( --wh );
height: var( --wh );
border: 1px solid black;
border-radius:var(--r);
margin: var(--m);
display: inline-block;
cursor:pointer;
}
/*
Use the pseudo element :after to
display the number of the square.
This uses the `data-id` attribute
assigned within Javascript.
*/
#results>div:after {
display:flex;
flex-direction:column;
justify-content:center;
align-content:center;
align-items:center;
flex:1;
margin:auto;
content: attr(data-id);
color:black;
text-shadow:0 0 15px rgba(255,255,255,1);
height:100px;
}
/*
modify the display for certain colours
to aid clarity
*/
#results>div.odd:after{
text-shadow:0 0 15px rgba(0,0,0,1);
}
#results>div.prime:after{
text-shadow:0 0 15px rgba(0,0,0,1);
color:white;
}
/*
The basic 3 colours to suit the odd/even/prime
status of each square.
*/
.even {
background: green;
}
.odd {
background: yellow
}
.prime {
background: red
}
h1,h2,h3{
text-align:center;
}
<div id='results'></div>
The idea here is to create a container for all of the blocks and set the display style attribute of this container to flex, style.flewrap to wrap and you can control how many blocks you want per line using style.width attribute.
After creating this element you would want to append to it your dynamically created blocks like p2.appendchild(p1);
Here is the code :
let p2 = document.createElement('div');
p2.className= 'p2';
p2.style.display = 'flex';
p2.style.flexwrap = 'wrap';
p2.style.width = '800px'
for (i = 0; i <= 101; i++) {
...
for every document.body.append(p1); --> p2.append(p1);
...
}
document.body.appendChild(p2);
I am creating a scrabble game with JavaScript and I have an issue. I have this function that creates scrabble tiles inside a tile rack div. I also have an event listener that listens for when the tile divs are clicked. When a section on the board is clicked, and then the tile div is clicked it places the tile on the board and then it would be removed from the the parent div(tile rack). How this works is this: I create an array which has those tile divs inside and then when I remove the div from inside the array, I would override the parent div(tile rack) with the new array. all this happens very well but the issue now is that when the old tiles overrides the new tiles in the parent div, the event listener does not work again.
here is my code and a link to my entire code explaining this:
let bag = ["A|1","A|1","A|1","A|1","A|1","A|1","A|1","A|1","A|1","B|3","B|3","C|3","C|3","D|2","D|2","D|2","D|2","E|1","E|1","E|1","E|1","E|1","E|1","E|1","E|1","E|1","E|1","E|1","E|1","F|4","F|4","G|2","G|2","G|2","H|4","H|4","I|1","I|1","I|1","I|1","I|1","I|1","I|1","I|1","I|1","J|8","K|5","L|1","L|1","L|1","L|1","M|3","M|3","N|1","N|1","N|1","N|1","N|1","N|1","O|1","O|1","O|1","O|1","O|1","O|1","O|1","O|1","P|3","P|3","Q|10","R|1","R|1","R|1","R|1","R|1","R|1","S|1","S|1","S|1","S|1","T|1","T|1","T|1","T|1","T|1","T|1","U|1","U|1","U|1","U|1","V|4","V|4","W|4","W|4","X|8","Y|4","Y|4","Z|10","|","|"];
// to fill the plate or stick with tiles from the bag array
let player1 = [];
let player2 = [];
let player1plate = document.getElementById("plate1");
let player2plate = document.getElementById("plate2");
// var tile = bag[Math.floor(Math.random() * bag.length)];
// FILL THE PLATE OR STICK WITH TILES
function fillStick(player, numberOfTilesNeeded, playerplate, id) {
let insert = "";
for (let i = 0; i < numberOfTilesNeeded; i++) {
randomIndex = Math.floor(Math.random() * bag.length);
player.push(bag[randomIndex]);
bag.splice(randomIndex, 1);
}
for (let j = 0; j < player.length; j++) {
insert += `
<div class="tile" id="${id}${j}">
<h2> ${player[j].split("|")[0]}</h2>
<p>${player[j].split("|")[1]}</p>
</div>`;
}
playerplate.innerHTML = insert;
// console.log(bag);
console.log(player1);
}
fillStick(player1, 7, player1plate, "tile");
fillStick(player2, 7, player2plate, "rile");
function removeTile(player, playerplate, id) {
let insert = "";
for (let j = 0; j < player.length; j++) {
insert += `
<div class="tile" id="${id}${j}">
<h2> ${player[j].split("|")[0]}</h2>
<p>${player[j].split("|")[1]}</p>
</div>`;
}
playerplate.insertAdjacentHTML("beforeend",insert);
console.log(playerplate);
}
// for the tiles on the rack/plate to click and be placed on the board
let tileClicked = 0;
let allTiles = document.querySelectorAll(".tile");
allTiles.forEach((e) => {
e.addEventListener("click", () => {
for (let i = 0; i < allTiles.length; i++) {
allTiles[i].setAttribute("class", "tile");
}
if (tileClicked == e.id) {
e.setAttribute("class", "tile");
tileClicked = 0;
} else {
e.setAttribute("class", "tile active");
tileClicked = e.id;
if (clicked != 0) {
document
.getElementById(clicked)
.setAttribute(
"style",
"background: #dfb15b; flex-direction: column;"
);
document.getElementById(clicked).setAttribute("class", "tilesections");
document.getElementById(clicked).innerHTML = e.innerHTML;
if (tileClicked.split("e")[0] == "til") {
player1.splice(tileClicked.split("e")[1], 1);
removeTile(player1, player1plate, "tile")
} else {
player2.splice(tileClicked.split("e")[1], 1);
removeTile(player2, player2plate, "rile")// where i stopped
console.log(player2);
}
clicked = 0;
tileClicked = 0;
e.setAttribute("class", "tile");
}
}
// console.log(e.id);
// console.log(player1);
});
});
to understand the problem better to can check the full code with this link
https://codepen.io/crentsil/pen/WNpeoKo
I think you should approach this question a little bit differently. Instead of adding an even listener on every single tile, you should add one on the container of the tiles. When you click an inner tile the event will "bubble" upwards. When it reaches the container div, you can catch it and get the originally clicked tile with the event.target attribute of the event parameter.
HTML:
<div id="board">
<div id="1"> 1 </div>
<div id="2"> 2 </div>
<div id="3"> 3 </div>
</div>
CSS
#board > div
{
width: 50px;
height: 50px;
background-color: gray;
margin: 10px;
}
JS
document.getElementById('board').addEventListener('click', (e) =>
{
let t = e.target
alert(`${t.id} clicked`)
})
I am trying to append a to the center of a 3x3 grid. Right now the tile is the last grid-item.
The divs are created using an event listener that triggers a function with a for loop.
function displayDino(){
for (var i = 0; i < dinoData.length; i++) {
const dinoDiv = document.createElement('div');
dinoDiv.className = 'grid-item';
dinoDiv.innerHTML = `<h3>${dinoData[i]["species"]}<h3><img src="images/${(dinoData[i]["species"].toLowerCase())}.png"><p>${dinoData[i]["fact"]}</p>`;
document.getElementById('grid').appendChild(dinoDiv);
}
}
I have another function that appends the div I want centered to the grid:
function displayHuman(){
const humanDiv = document.createElement('div');
humanDiv.className = 'grid-item';
humanDiv.innerHTML = `<h3>${human.name()}<h3><img src="images/human.png">`;
document.getElementById('grid').appendChild(humanDiv);
}
How can I generate this grid while making sure a specific div appears at the center of the grid every time?
Any help would be much appreciated. Thank you!
If the grid is always 3x3 and you want to center the human entry horizontally and vertically, just wait until you are at index 5, add the human, remember that you added him and continue iterating through the array.
function displayElements(){
var humanAdded = false;
for (var i = 0; i < dinoData.length; i++) {
const elemDiv = document.createElement('div');
elemDiv .className = 'grid-item';
if(humanAdded == false && i == 5){
elemDiv .innerHTML = `<h3>${human.name()}<h3><img src="images/human.png">`;
humanAdded = true;
i--;
}else{
elemDiv .innerHTML = `<h3>${dinoData[i]["species"]}<h3><img src="images/${(dinoData[i]["species"].toLowerCase())}.png"><p>${dinoData[i]["fact"]}</p>`;
}
document.getElementById('grid').appendChild(elemDiv);
}
}
My thoughts::: If you know where to put your single data in a grid.. just use grid-row, grid-column css for that grid-child... Just ignore the other grid-childs and just style that particular child... you can have more than one humans which you can put whereever you like this way...
var dinoData = ["Plateosaurus","Abelisaurus","Barsboldia","Litosoraus","Platicore","Manticore","Trynasoraus","Sicocoreus"];
var human = { name: "MEEEEEEEE"};
function displayDino() {
for (var i = 0; i < dinoData.length; i++) {
const dinoDiv = document.createElement('div');
dinoDiv.className = 'grid-item';
dinoDiv.innerHTML = `<h3>${dinoData[i]}<h3>`;
document.getElementById('grid').appendChild(dinoDiv);
}
}
function displayHuman() {
const humanDiv = document.createElement('div');
humanDiv.className = 'grid-item human';
humanDiv.innerHTML = `<h3>${human.name}`;
document.getElementById('grid').appendChild(humanDiv);
}
displayDino();displayHuman();
#grid{
display: grid;
grid-template-columns: auto auto auto;
}
.grid-item{
display: flex;
padding: 50px;
justify-content: center;
align-items: center;
}
.human{
grid-row: 2/3;
grid-column: 2/3;
}
<div id="grid">
</div>
I am making a program in javascript that will change the css style (in this case background color) of an element after some delay, similar to a traffic light.
The problem is this: when you click the button, the button's onclick listener function is entered. In the function are for loops to iterate through each cell and change its color. Each pass through the loop should update one of the cells colors, but does not. What actually happens is all the cells are updated after the button's onclick listener function is finished.
Here is a link to a shortened version of my problem that I made https://jsfiddle.net/lilweege/4291vjto/6/
let main = document.getElementById('main')
// create 'cells' which are just empty divs (refer to css styles above)
let cells = []
for (let x = 0, numCells = 15; x < numCells; x++) {
let cell = document.createElement("DIV")
cell.setAttribute('class', 'cell')
cells.push(cell)
main.appendChild(cell)
}
// create button to run main logic
const run = document.createElement("BUTTON")
run.innerHTML = 'change colors'
run.addEventListener('click', function() {
console.log('starting program');
// reset all cell colors
for (let cell of cells) {
cell.style.background = 'white'
}
for (let cell of cells) {
// change color of cell
cell.style.background = `hsl(${cells.indexOf(cell) * (360 / cells.length)}, 100%, 50%)`
// halt program for 500ms
sleep(100)
}
console.log('done');
})
main.appendChild(run)
// sleep function halts entire program during period of ms
function sleep(milliseconds) {
console.log(`waiting ${milliseconds} milliseconds`);
const start = Date.now();
let current = null;
do {
current = Date.now();
} while (current - start < milliseconds);
}
.main {
display: flex;
}
.cell {
width: 20px;
height: 20px;
border: 1px solid black;
margin: 1px;
}
<div id="main" class="main"></div>
This is also the case when adding an element, changing some other property such as innerHTML, or some other change in the DOM.
Also I don't suspect my 'sleep' function to be the problem, because all it is doing is halting the entire program in the browser until an amount of milliseconds have passed (it calls Date.now() until the delta of current time and start time is larger than the passed in amount).
Any pointers or solutions would be much appreciated, thanks!
Your sleep function is the problem. It's semi-permanently running a blocking loop. All of the current tab (or frame)'s resources are going towards resolving that loop, so that once it finishes, the event loop can continue on and start rendering. But if the nested loop (and the event listener) doesn't resolve until 10 seconds later, the browser won't be able to even start to update the display until 10 seconds later.
Await a Promise which uses setTimeout instead - setTimeout doesn't block processing or rendering, unlike a loop that goes through tens of thousands of iterations:
const sleep = ms => new Promise(res => setTimeout(res, ms));
const main = document.getElementById('main')
const cells = []
for (let x = 0, numCells = 20; x < numCells; x++) {
const cell = document.createElement("DIV")
cell.setAttribute('class', 'cell')
cells.push(cell)
main.appendChild(cell)
}
const run = document.createElement("BUTTON")
run.innerHTML = 'change colors'
run.addEventListener('click', async function() {
for (let cell of cells) {
cell.style.background = `hsl(${cells.indexOf(cell) * (360 / cells.length)}, 100%, 50%)`
await sleep(500)
}
console.log('done');
})
main.appendChild(run)
.main {
display: flex;
}
.cell {
width: 20px;
height: 20px;
border: 1px solid black;
margin: 1px;
}
<div id="main" class="main"></div>
There's almost never a good reason to use a while loop to wait for a Date.now() to reach a threshold - it's extremely computationally expensive, is user-unfriendly (since the frame can't be interacted with during that time), and can produce unexpected results (like what you're experiencing here).
CertainPerformance responded faster than me while I was working on my side on the same response.
I just made some improvements to the code,
I also believe that it is better to place the sleep before the coloring...
const main = document.getElementById('main')
, cells = []
, numCells = 16
, run = document.createElement('button')
, sleep = ms => new Promise(res => setTimeout(res, ms))
;
let InOut = 0 // to reverse colors order
;
run.textContent = 'set colors'
;
for (let x=0; x < numCells; x++) // create 'cells' which are just empty divs (refer to css above)
{
cells[x] = main.appendChild(document.createElement('div'))
}
main.appendChild(run) // button to run main logic
;
run.onclick = async _=>
{
for (let cell of cells)
{ cell.style.backgroundColor = null }
for (let x in cells)
{
await sleep(200)
cells[x].style.backgroundColor = `hsl(${(Math.abs(InOut-x)) *(360 /numCells)}, 100%, 50%)`
}
InOut = InOut ? 0 : (numCells-1)
}
#main {
display: flex;
}
#main div {
display: inline-block;
width: 1.2em;
height: 1.2em;
border: 1px solid black;
margin: .1em;
background-color: white;
}
#main button {
margin-left:.3em
}
<div id="main"></div>
I am working on an Etch-A-Scetch project. I created grid which contains a certain amount of squares of the same size (the user is able to type in the amount of squares which should be displayed). To create the squares I used CSS grid and a Javascript for loop. Now I want to add event listeners, which change the background of each Square when moving over it. Unfortunately, it always shows errors when I try to add some. The current code doesn't show an error, it just doesn't do anything.
The method createSquares() should just create and add the amount of squares to the DOM. The user types in an amount, for example 10, and the displayed squares are 10 in x-direction and 10 in y-direction --> makes 100 squares in total. After that I want to add an event listener, which changes the background color of the square the user hovers over (the background color should stay changed). I am thankful for any help, because I'm really clueless :D
let squareDiv = document.querySelector('.squareDiv');
let squares = document.getElementById('#squares')
let squareAmount = 10;
function blackColor() {
this.style.backgroundColor = '#000';
this.style.border = '0px';
}
function createSquares() {
for (i = 0; i < squareAmount * squareAmount; i++) {
squares = document.createElement('div');
squares.setAttribute("id", "squares");
// squares.setAttribute("onmouseover", "addEventListener")
squares.style.display = 'grid';
squareDiv.style.setProperty('--columns-amount', squareAmount);
squareDiv.style.setProperty('--rows-amount', squareAmount);
squareDiv.appendChild(squares);
}
}
createSquares();
if (squares) {
squares.addEventListener('mouseover', _ => {
squares.style.backgroundColor = blackColor;
});
}
<div class="squareDiv"></div>
<div id="squares"></div>
You likely need something like this
I fixed the script, now fix the CSS
let container = document.getElementById("container")
let squareAmount = 5;
function getRandom() {
return '#'+Math.floor(Math.random()*16777215).toString(16);
}
function colorIt(sq) {
sq.style.backgroundColor = document.getElementById("random").checked? getRandom() : '#000';
sq.style.border = '0px';
}
function createSquares() {
let grid = document.createElement('div');
grid.setAttribute("id","squares")
grid.classList.add("grid");
for (i = 0; i < squareAmount * squareAmount; i++) {
square = document.createElement('div');
square.classList.add("square");
grid.appendChild(square);
}
container.innerHTML="";
container.appendChild(grid)
}
createSquares();
container.addEventListener('mouseover',
e => {
const target = e.target;
if (target.matches(".square")) colorIt(target)
}
);
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
grid-auto-rows: 1fr;
}
.grid::before {
content: '';
width: 0;
padding-bottom: 100%;
grid-row: 1 / 1;
grid-column: 1 / 1;
}
.grid > *:first-child {
grid-row: 1 / 1;
grid-column: 1 / 1;
}
/* Just to make the grid visible */
.grid > * {
background: rgba(0,0,0,0.1);
border: 1px white solid;
}
<label><input type="checkbox" id="random" />Random</label>
<div id="container"></div>
You have already created the element in DOM, please remove this.
while creating the element using function createSquares assign class instead of ID. Since, you should have only element with one ID.
Move the addEventListener inside the function after you have created the element.
When creating similar html elements with same properties it is better to group them together with class and not id. This is good because it becomes simple to loop these html elements with forEach or other looping methods you may prefer.
let squareDiv = document.querySelector('.squareDiv');
let squares = document.getElementById('#squares')
let squareAmount = 10;
function blackColor() {
this.style.backgroundColor = '#000';
this.style.border = '0px';
}
function createSquares() {
for (i = 0; i < squareAmount * squareAmount; i++) {
squares = document.createElement('div');
squares.setAttribute("class", "squares");
squares.setAttribute("style", "width: 100px; height: 100px; background: #090; margin-bottom: .3rem;");
// squares.setAttribute("onmouseover", "addEventListener")
squares.style.display = 'grid';
squareDiv.style.setProperty('--columns-amount', squareAmount);
squareDiv.style.setProperty('--rows-amount', squareAmount);
squareDiv.appendChild(squares);
}
}
createSquares();
if (squares) {
squares.addEventListener('mouseover', _ => {
squares.style.backgroundColor = blackColor;
});
}
<div class="squareDiv"></div>
<div id="squares"></div>