I am trying to write a simple function for etch-a-sketch and came across this problem. I attached eventListener to the color and erase buttons like this:
eraseBtn.addEventListener("click", function erase(){
document.addEventListener("mouseover", function eraser(event){
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
elem.style.backgroundColor = "";
});
});
coloringBtn.addEventListener("click", function color(){
document.addEventListener("mouseover", function coloring(event) {
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
let randColor1 = Math.round(Math.random() * 255);
let randColor2 = Math.round(Math.random() * 255);
let randColor3 = Math.round(Math.random() * 255);
elem.style.backgroundColor = `rgb(${randColor1}, ${randColor2}, ${randColor3})`;
});
});
This functions as it is supposed to i.e, when I click color you can draw color and by clicking the erase you can erase the color you drew. However, this variant works on the first click and doesn't work afterwards:
function erase(){
document.addEventListener("mouseover", eraser);
}
function eraser(event){
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
elem.style.backgroundColor = "";
};
eraseBtn.addEventListener("click", erase);
function color(){
document.addEventListener("mouseover", coloring);
};
function coloring(event) {
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
let randColor1 = Math.round(Math.random() * 255);
let randColor2 = Math.round(Math.random() * 255);
let randColor3 = Math.round(Math.random() * 255);
elem.style.backgroundColor = `rgb(${randColor1}, ${randColor2}, ${randColor3})`;
};
coloringBtn.addEventListener("click", color);
Here is the working demo for the second case: Codepen Link because SO snippet is not working for me.
Why is the second one not working as expected and the first one is working fine?
What is lacking here is the ability to remove event listeners. Presently both erasing and coloring can happen at once on mouseover. Additionally, some booleans to track state will help guarantee the outcome.
let erasingEnabled = false;
let coloringEnabled = false;
eraseBtn.addEventListener("click", function erase(){
erasingEnabled = !erasingEnabled;
if (erasingEnabled) {
coloringEnabled = false;
document.removeEventListener("mouseover", coloring);
document.addEventListener("mouseover", eraser);
} else {
document.removeEventListener("mouseover", eraser);
document.addEventListener("mouseover", coloring);
}
});
coloringBtn.addEventListener("click", function color(){
coloringEnabled = !coloringEnabled;
if (coloringEnabled) {
erasingEnabled = false;
document.removeEventListener("mouseover", eraser);
document.addEventListener("mouseover", coloring);
} else {
document.removeEventListener("mouseover", coloring);
document.addEventListener("mouseover", eraser);
}
});
function eraser(event){
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
elem.style.backgroundColor = "";
}
function coloring(event) {
let elem = event.target.closest('div');
if (!elem || elem.parentNode.id != "container") return;
let randColor1 = Math.round(Math.random() * 255);
let randColor2 = Math.round(Math.random() * 255);
let randColor3 = Math.round(Math.random() * 255);
elem.style.backgroundColor = `rgb(${randColor1}, ${randColor2}, ${randColor3})`;
}