Currently, I am delving into Javascript on the Odin Project, tackling the Etch-a-Sketch exercise. This involves creating a board where you can draw with your cursor. As part of the exercise, there's a requirement to add a resize button that allows users to specify the number of tiles on each side of the board, capped at 100 (for a 100x100 board). I managed to implement this feature successfully, but encountered performance issues as my browser struggled with around 60 tiles and crashed at the maximum limit.
The exercise primarily focuses on using Javascript to manipulate the DOM. I wrote a script to generate a div container for the entire board, with a default 16x16 board created when the page loads. Each tile is represented by a div with an event listener that changes the tile's color based on a CSS rule associated with a specific class.
Upon clicking the reset button, a function is triggered. This function resets the classes for all tiles and prompts the user to enter a new value. Once a valid value is received, the CSS rule tied to the original div container is updated with the specified number of rows and columns. Subsequently, existing tiles are removed, and new tiles are added to the div container.
Here's the code for the HTML, CSS, and JavaScript:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<button class="reset">Reset and resize</button>
</body>
</html>
body {
display: flex;
flex-direction: column;
}
.reset {
align-self: flex-start;
}
.sketchContainer {
width: 900px;
height: 900px;
border: solid 1px black;
display: grid;
align-self: center;
grid-template-rows: repeat(16, auto);
grid-template-columns: repeat(16, auto);
}
div.tileHovered {
background-color: #c3a375;
}
generateDefaultGrid();
placeEventListenersOnTiles();
const button = document.querySelector(".reset");
button.addEventListener("click", reset);
function generateDefaultGrid() {
const sketchContainer = document.createElement("div");
document.body.appendChild(sketchContainer);
sketchContainer.classList.add("sketchContainer");
const gridTile = document.createElement("div");
sketchContainer.appendChild(gridTile);
gridTile.classList.add("gridTile");
let clonedTile;
for (let i = 0; i < 16*16-1; i++) {
clonedTile = gridTile.cloneNode();
sketchContainer.appendChild(clonedTile);
}
}
function placeEventListenersOnTiles() {
let allTiles = document.querySelectorAll(".gridTile");
allTiles.forEach(element => {
element.addEventListener("mouseover", changeColor);
});
}
function changeColor() {
this.classList.add("tileHovered");
}
function reset() {
let allTiles = document.querySelectorAll(".tileHovered");
allTiles.forEach(element => {
element.classList.remove("tileHovered");
});
resizeGrid();
}
function resizeGrid() {
let newSize = prompt("How many squares do you want per side of the Etch-a-Sketch?", "Please insert a number inferior or equal to 100.");
if (newSize > 100) {
newSize = prompt("Sorry, that number is too high!", "Please insert a number inferior or equal to 100.");
} else if (Math.sign(newSize) == 0 || Math.sign(newSize) == -1) {
newSize = prompt("Only integers between 1 and 100, please!", "Please insert a number inferior or equal to 100.");
} else if (newSize === null) {
generateDefaultGrid();
} else {
const styleSheet = document.styleSheets[0];
styleSheet.cssRules[2].style.gridTemplateRows=`repeat(${newSize}, auto)`;
styleSheet.cssRules[2].style.gridTemplateColumns=`repeat(${newSize}, auto)`;
removeAllTiles();
generateUserGrid(newSize);
}
}
If you could take a look at my project on GitHub, I would appreciate any insights on why my script is inefficient and how I can optimize it. This aspect wasn't covered in the course, and I'm still new to this area. Thank you in advance!