JS - selecting all divs created by document.createElement - Etch-a-Sketch


#1

Hello,
I have been trying to figure this out for almost 2 weeks and thought maybe its best if I ask for help. I did search for an answer to this question on this and other forums but I couldn’t find any solution that would work for me.

A little explanation of my code - When I was building the etch-a-sketch project I accidentally came across a way to have the div color continually change after mouse hover. I liked it so I am trying to incorporate it in my final code buy giving the user the option to select between 3 radio buttons.

  1. “darker”(%10 increase till black)
  2. “colors”(random color generation)
  3. “psychedelic”(after hover div changes color every 1/10 a second)
    I have all of these functioning in separate html files. I am now trying to combine them into one file.

The problem I am having is that now on eventListener mouseover, only the bottom right div (I guess the last one created) changes color instead of all of them. I am creating these divs using document.createElement(“div”) in my initial function that creates the grid.

I have tried a lot of things and cant really remember all the things I have tried but most recently I have tried using querySelectorAll to select all divs with classname “boxes” but either I am doing it wrong or it wont work for my code.

That is my main issue, if I can clarify at all let me know.

I do have another issue also in regards to changing selections with the radio buttons so if anyone knows of a better way to give the user the 3 options mentioned above I am all ears.

Thanks, any help would be great.

    <!DOCTYPE html>
<html>

<head>
	<title>sketch</title>
	<link href="style.css" rel="stylesheet" type="text/css">
</head>

<body>
	<header>
		<h1 class="title">Etch-A-Sketch</h1>
	</header>
	<div id="wrapper">
		<button id="btn">Reset Grid</button>
    </div>
	<div id="checkBoxes">
  		<input type="radio" name = "option" id="black" checked="checked">darker<br>
  		<input type="radio" name = "option" id="color">colors<br>
  		<input type="radio" name = "option" id="psych"> psychedelic<br>
	</div>
	<div id="container">
	</div>
	<div id="prompt">
	</div>


<script type="text/javascript">

const container = document.getElementById("container");
const rstbtn = document.getElementById("btn");
const black = document.getElementById("black");
const color = document.getElementById("color");
const psych = document.getElementById("psych");
const checks = document.getElementById("checkboxes");

initGrid(16);

//reset button function
rstbtn.addEventListener("click", function(){
	let newNum = window.prompt ("Enter how many tiles you would like the new grid to be.", "16");
	container.innerHTML="";
	initGrid(newNum);
});

//grid initializing function
function initGrid(num){
	for (let i=0; i<num; i++){
		for (let j=0; j<num; j++){
			box = document.createElement("div");
    		let boxSize = (690/num) + "px";
    		box.style.height = boxSize;
     		box.style.width = boxSize;
			box.classList.add("boxes");
			container.appendChild(box);
			box.addEventListener ("mouseover",function(){
				box.style.backgroundColor = draw();
			})
		}
	}	
};



//choice between radio buttons
function draw(){
	let choice;
	if (black.checked == true){
		choice=darker();
	}else if (color.checked == true){
		choice=colors();
	}else if(psych.checked == true){
		choice=psychedelic();
	}else{
		choice=darker();
	}
	box.style.backgroundColor = choice;
};


//black function
function darker(){
	let ogRed = 255;
	let ogGreen = 255;
	let ogBlue = 255;
	console.log("darker")
	if (box.style.backgroundColor) {
		let ogColor = box.style.backgroundColor;
		let colorsSplit = ogColor.slice(4,ogColor.length-1).split(", ");
		ogRed = Number(colorsSplit[0]);
		ogGreen = Number(colorsSplit[1]);
		ogBlue = Number(colorsSplit[2]);
	}
	let red = ogRed - 24;
	let green = ogGreen - 24;
	let blue = ogBlue - 24;
	return "rgb(" + red +","+ green +","+ blue +")";
};



//color function
function colors() {
	let randomNum = Math.floor(Math.random() * 10);
	console.log("colors")
	if (randomNum == 0){
		return "yellow";
	}else if(randomNum == 1){
		return "orange";
	}else if(randomNum == 2){
		return "red";
	}else if(randomNum == 3){
		return "maroon";
	}else if(randomNum == 4){
		return "blue";
	}else if(randomNum == 5){
		return "indigo";
	}else if(randomNum == 6){
		return "pink";
	}else if(randomNum == 7){
		return "purple";
	}else if(randomNum == 8){
		return "green";
	}else if(randomNum == 9){
		return "lime";
	}else{
		return "black";
	}
};
	

//used for the "psych" selection in the "setInterval" function below. generates randon number 
function randomInt(min, max){
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

//psych function
function psychedelic(){	
	let disco = setInterval(function(){
	console.log("psychedelic");
	let r = randomInt(0,255);
	let g = randomInt(0,255);
	let b = randomInt(0,255);
	let disco = "rgb("+ r + "," + g + "," + b + ")";
	box.style.backgroundColor = disco;
	},100)
};	

</script>

#2

Hi,

I think your problem is because you are not using the event to figure out which cell in the grid the mouse is over.

function draw will be invoked whenever there is an event in any of the cells. Pass the event to the function as in Draw(e).

Use console.log(e) inside the function to look at the event and figure out which cell triggered the event, based on that update box using query selector to make it point to the cell and set the colour. you might have to use jquery here.

hope this helps.


#3

Hi @Ghassan_T
Thanks for the advice. I have to admit I am not sure what you mean with “draw(e)” to be honest all the (e)/event stuff with functions is something I am struggling to grasp.

None the less you have motivated me to look at this in a different direction and pointed me toward new potential options.

It still seems that no matter what I do or how I go about attaching the event listener to the actual boxes in the grid (i.e. querySelectorAll, getElementsByClassName, container.children) the best outcome I can get is that only that bottom right box changes with mouseOver… (actually I can get it to change the 1st (top left) also but that obviously isnt any better.) I will keep messing with it and hopefully something will work for me.

Thanks again, I do appreciate the advice!


#4

hi @CaptainSensible,

do the first exercise with Wes Bos, it helped me a lot with events.
there are a few tricks in there that you can use, pause the video and explore them.

Do the first exercise in Wes Bos’s JavaScript30 program by cloning the repo at https://github.com/wesbos/JavaScript30. Check out the Video Tutorial for instructions on the project.


#5

@Ghassan_T Thanks, I have already gone through that video but maybe I should go back through it again.

I have made a little progress by using “this” in my draw() function instead of “box” to change the style.background and changing the eventListener to
boxes = document.querySelectorAll(".boxes");
boxes.forEach(box => box.addEventListener(‘mouseover’, draw));
I dont understand all of the above but it seems to be working better.
I am still having other issues with some of my functions but its a little bit of progress.

anyway… I will go back and check out the drum kit build video. I did enjoy it the first time around and have been meaning to go back and watch it again.

Again, thanks for the help and advice. It is appreciated!