Sketchpad画板尺寸与背景色功能异常问题求助
Sketchpad 项目问题修复方案
问题1:修改画板尺寸后无法绘制、getPointerMessage()无法执行
问题根源
- 每次调用
populatedBoard()时未清空画板内旧的网格元素,新元素叠加导致网格布局错乱,鼠标事件触发异常。 - 重复给
.board绑定click事件,点击时click变量被多次取反,状态逻辑混乱。 - 用户取消尺寸输入时,
getBoardSize()返回undefined,传入populatedBoard()后生成无效网格。
修复核心调整
// 全局变量新增当前背景色存储 let color = 'black'; let click = true; let currentBgColor = 'rgb(134, 101, 212)'; function populatedBoard(size) { let board = document.querySelector('.board'); // 清空旧网格元素,避免叠加 board.innerHTML = ''; board.style.gridTemplateColumns = `repeat(${size}, 1fr)`; board.style.gridTemplateRows = `repeat(${size}, 1fr)`; let divSize = size * size; for (let i = 0; i < divSize; i++) { let fill = document.createElement('div'); fill.className = 'sq'; fill.style.backgroundColor = currentBgColor; fill.addEventListener('mouseover', paintBoard); board.appendChild(fill); } } // 将board的click事件移到外部,仅绑定一次 document.querySelector('.board').addEventListener('click', () => { click = !click getPointerMessage(); }); function getButtonSize() { let sizeButton = document.querySelector('.select-size'); sizeButton.addEventListener('click', () => { let size = getBoardSize(); // 仅当尺寸有效时生成新网格 if (size && size >=1 && size <=64) { populatedBoard(size); } }) }
问题2:背景色修改与清除按钮冲突
问题根源
clearBoard()硬编码了重置颜色为初始紫色,未同步用户设置的背景色,导致清除后背景色回退。
修复核心调整
function clearBoard() { let squares = document.querySelectorAll('.sq'); // 使用存储的当前背景色重置网格 squares.forEach((sq) => sq.style.backgroundColor = currentBgColor); } function changeBg() { let boardBackground = document.querySelector('.change-bg'); let board = document.querySelector('.board'); boardBackground.addEventListener('click', () => { currentBgColor = 'red'; board.style.backgroundColor = currentBgColor; // 同步更新现有网格元素颜色 let squares = document.querySelectorAll('.sq'); squares.forEach((sq) => sq.style.backgroundColor = currentBgColor); }) }
问题3:重复设置相同尺寸时画板缩小、点击无效
问题根源
未清空旧网格元素,导致画板内元素数量过载,网格布局被挤压,旧鼠标事件残留引发逻辑混乱。
修复方式
已在populatedBoard()开头添加board.innerHTML = '';,每次生成新网格前清空旧内容,彻底解决元素叠加问题。
完整修复后代码
JavaScript
let color = 'black'; let click = true; let currentBgColor = 'rgb(134, 101, 212)'; function populatedBoard(size) { let board = document.querySelector('.board'); board.innerHTML = ''; board.style.gridTemplateColumns = `repeat(${size}, 1fr)`; board.style.gridTemplateRows = `repeat(${size}, 1fr)`; let divSize = size * size; for (let i = 0; i < divSize; i++) { let fill = document.createElement('div'); fill.className = 'sq'; fill.style.backgroundColor = currentBgColor; fill.addEventListener('mouseover', paintBoard); board.appendChild(fill); } } function paintBoard() { if (click) { if (color === 'random') { this.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 50%)`; } else { this.style.backgroundColor = color; } } } function changeColor(input) { color = input; } function clearBoard() { let squares = document.querySelectorAll('.sq'); squares.forEach((sq) => sq.style.backgroundColor = currentBgColor); } function getPointerMessage() { let pointerMessage = document.querySelector('.pointer-message'); pointerMessage.textContent = click ? 'You are allowed to paint ✅' : 'You are not allowed to paint 🟥'; } function getBoardSize() { let errorMessage = document.querySelector('.error-message'); let input = prompt('Select a board size'); // 处理用户取消输入的情况 if (input === null) { errorMessage.textContent = ''; return null; } // 转换为数字并验证 input = parseInt(input); if (isNaN(input) || input <= 0) { errorMessage.textContent = 'Negative numbers not allowed'; } else if (input > 64) { errorMessage.textContent = 'Set a number between 1 and 64!'; } else { errorMessage.textContent = ''; return input; } } function getButtonSize() { let sizeButton = document.querySelector('.select-size'); sizeButton.addEventListener('click', () => { let size = getBoardSize(); if (size) { populatedBoard(size); } }) } function changeBg() { let boardBackground = document.querySelector('.change-bg'); let board = document.querySelector('.board'); boardBackground.addEventListener('click', () => { currentBgColor = 'red'; board.style.backgroundColor = currentBgColor; let squares = document.querySelectorAll('.sq'); squares.forEach((sq) => sq.style.backgroundColor = currentBgColor); }) } // 初始化绑定事件 document.querySelector('.board').addEventListener('click', () => { click = !click getPointerMessage(); }); getButtonSize(); populatedBoard(32);
CSS(无需修改)
body { display: flex; flex-direction: column; justify-content: center; align-items: center; } .board { display: grid; width: 500px; height: 500px; background: rgb(134, 101, 212); border: 3px dashed rebeccapurple; border-radius: 5px; } .error-message { font-weight: bold; font-size: 12px; color: red; margin-top: 10px; margin-bottom: 20px; }
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="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <link rel="stylesheet" href="sketchpad.css"> <script src="sketchpad.js" defer></script> <title>Etch a Sketch!</title> </head> <body> <h1>Sketchpad!</h1> <button class="btn btn-primary select-size">Select size</button> <span class="error-message"></span> <span class="pointer-message">You are allowed to paint ✅</span> <div class="board"></div> <div class="buttons"> <button class="btn btn-dark" onclick="changeColor('black')">Black</button> <button class="btn btn-danger" onclick="changeColor('red')">Red</button> <button class="btn btn-warning" onclick="changeColor('random')">Random</button> <button class="btn btn-secondary" onclick="clearBoard()">Clear</button> <button class="btn btn-danger change-bg">Red background</button> </div> </body> </html>
内容的提问来源于stack exchange,提问作者Quickpois0n
相关产品推荐
相关产品推荐

