Etch-A-Sketch项目两大功能异常问题求助
Etch-A-Sketch 问题修复方案
问题1:Opacity按钮切换后无法递增透明度
原因
- 每次点击工具按钮时,都会给单元格添加新的
mouseenter监听器,多个监听器叠加导致Opacity逻辑被其他工具覆盖。 - Clear按钮将单元格
backgroundColor设为#ffffff,Opacity逻辑仅识别rgba格式的背景色,白色不会触发递增分支,只会重置为0.1透明度的黑色。 - 直接从样式字符串解析透明度易受浏览器格式差异影响,可靠性低。
修复方案
- 用全局变量记录当前激活工具,统一在单元格的
mouseenter事件中执行对应逻辑,避免重复绑定监听器。 - 给每个单元格添加自定义属性存储透明度值,替代从样式字符串解析的方式。
问题2:Clear后Grid背景色无法显示
原因
Clear按钮将单元格backgroundColor设为不透明的#ffffff,完全覆盖了Grid的背景色,导致Grid背景无法透出。
修复方案
- Clear时将单元格
backgroundColor设为空字符串,让Grid背景色正常显示。
修改后的完整代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <script src="app.js" defer></script> <title>Etch-A-Sketch</title> </head> <body> <header> <h1>Etch-A-Sketch</h1> </header> <div class="grid-size"> <button class="btn-set-grid-size">Set Grid Size</button> <input type="text" id="grid-size"> </div> <p id="error-message">Error! Please, enter a number that is less or equal to 50!</p> <main class="main-content"> <div class="settings"> <div class="div-pen-color"> <label for="pen-color" class="label-custom-color" id="label-pen-color">Pen Color</label> <input type="color" id="input-pen-color" class="input-custom-color"> </div> <div class="div-background-color"> <label for="background-color" class="label-custom-color" id="label-background-color">Background Color</label> <input type="color" id="input-background-color" class="input-custom-color"> </div> <button id="btn-black">Black</button> <button id="btn-rainbow">Rainbow</button> <button id="btn-opacity">Opacity</button> <button id="btn-eraser">Eraser</button> <button id="btn-clear">Clear</button> </div> <div class="grid"></div> </main> </body> </html>
CSS
:root { --grid-cols: 1; --grid-rows: 1; } * { margin: 0; } header { text-align: center; padding: 20px; } .main-content { display: flex; align-items: center; justify-content: flex-start; gap: 95px; max-width: 1100px; margin: 0 auto; } .grid { display: grid; text-align: center; width: 500px; height: 500px; border: 5px solid black; grid-template-rows: repeat(var(--grid-rows), 1fr); grid-template-columns: repeat(var(--grid-cols), 1fr); margin-right: auto; } .grid-item { display: grid; border: 1px solid black; transition: 0.3s ease-in-out; margin: 0px; } .grid-size { display: flex; justify-content: center; align-items: center; } label { margin-right: 5px; } .settings { display: flex; flex-direction: column; justify-content: flex-start; gap: 30px; width: 200px; } #error-message { text-align: center; color: #ff0000; opacity: 0; margin: 10px; } .div-pen-color, .div-background-color { display: flex; justify-content: center; align-items: center; }
JavaScript
const body = document.querySelector("body"); const grid = document.querySelector(".grid"); const penCustomColor = document.querySelector("#input-pen-color"); const backgroundCustomColor = document.querySelector("#input-background-color"); let isMouseDown = false; let currentTool = "black"; // 默认激活黑色笔工具 document.body.onmousedown = () => (isMouseDown = true); document.body.onmouseup = () => (isMouseDown = false); // 初始化工具按钮切换事件 function initToolButtons() { document.querySelector("#btn-black").addEventListener("click", () => { currentTool = "black"; }); document.querySelector("#btn-rainbow").addEventListener("click", () => { currentTool = "rainbow"; }); document.querySelector("#btn-opacity").addEventListener("click", () => { currentTool = "opacity"; }); document.querySelector("#btn-eraser").addEventListener("click", () => { currentTool = "eraser"; }); // 自定义笔色选择后切换到自定义笔工具 penCustomColor.addEventListener("input", () => { currentTool = "customPen"; }); } // 初始化背景色设置事件 function initBackgroundColor() { backgroundCustomColor.addEventListener("input", () => { grid.style.backgroundColor = backgroundCustomColor.value; }); } // 处理单元格绘制逻辑 function handleCellDraw(cell) { cell.addEventListener("mouseenter", () => { if (!isMouseDown) return; switch (currentTool) { case "black": cell.style.backgroundColor = "black"; cell.dataset.opacity = "1"; break; case "rainbow": const rainbowColors = ["#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000"]; const randomColor = rainbowColors[Math.floor(Math.random() * rainbowColors.length)]; cell.style.backgroundColor = randomColor; cell.dataset.opacity = "1"; break; case "opacity": // 从自定义属性获取当前透明度,默认0 let currentOpacity = parseFloat(cell.dataset.opacity) || 0; if (currentOpacity < 1) { currentOpacity += 0.1; cell.style.backgroundColor = `rgba(0, 0, 0, ${currentOpacity.toFixed(1)})`; cell.dataset.opacity = currentOpacity.toFixed(1); } break; case "eraser": cell.style.backgroundColor = ""; cell.dataset.opacity = "0"; break; case "customPen": cell.style.backgroundColor = penCustomColor.value; cell.dataset.opacity = "1"; break; } }); } function makeGrid(rows, columns) { grid.style.setProperty("--grid-rows", rows); grid.style.setProperty("--grid-cols", columns); for (let i = 0; i < rows * columns; i++) { let cell = document.createElement("div"); cell.className = "grid-item"; cell.dataset.opacity = "0"; // 初始化透明度记录属性 grid.appendChild(cell); handleCellDraw(cell); } } // 初始化Clear按钮事件 function initClearButton() { const buttonClear = document.querySelector("#btn-clear"); buttonClear.addEventListener("click", () => { grid.childNodes.forEach((child) => { child.style.backgroundColor = ""; // 清空单元格背景,透出Grid背景 child.dataset.opacity = "0"; }); }); } // 初始化新网格创建功能 function createNewGrid() { let inputValue = document.querySelector("#grid-size"); let rows = 15; let columns = 15; inputValue.addEventListener("input", () => { rows = parseInt(inputValue.value); columns = parseInt(inputValue.value); }); const buttonNewGrid = document.querySelector(".btn-set-grid-size"); const errorMessage = document.querySelector("#error-message"); buttonNewGrid.addEventListener("click", () => { document.querySelectorAll(".grid-item").forEach((e) => e.remove()); if (!isNaN(rows) && rows <= 50) { errorMessage.style.opacity = 0; makeGrid(rows, columns); inputValue.value = ""; } else { errorMessage.style.opacity = 1; errorMessage.style.transition = "0.3s ease-in-out"; inputValue.value = ""; } }); } // 启动所有功能 initToolButtons(); initBackgroundColor(); makeGrid(15, 15); initClearButton(); createNewGrid();
内容的提问来源于stack exchange,提问作者ivooo369
相关产品推荐
相关产品推荐

