Estoy tratando de escribir una función simple para etch-a-sketch y me encontré con este problema. Adjunté eventListener a los botones de color y borrado como este:
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})`; }); });Esto funciona como se supone que debe hacerlo, es decir, cuando hago clic en color, puede dibujar el color y al hacer clic en borrar, puede borrar el color que dibujó. Sin embargo, esta variante funciona con el primer clic y no funciona después:
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);Aquí está la demostración de trabajo para el segundo caso: Codepen Link porque el fragmento SO no funciona para mí.
¿Por qué el segundo no funciona como se esperaba y el primero funciona bien?
Lo que falta aquí es la capacidad de eliminar los detectores de eventos . Actualmente, tanto el borrado como el coloreado pueden ocurrir a la vez al pasar el mouse. Además, algunos valores booleanos para rastrear el estado ayudarán a garantizar el resultado.
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})`; }