CSS Grid实现Etch-A-Sketch:列可调整但行数不变问题求助
问题:Etch-A-Sketch网格行数量不随输入变化,单元格呈矩形
正在完成The Odin Project基础课程的Etch-A-Sketch项目,初始为16×16网格,预期网格单元格数量随用户输入变化,但当前列数会更新,行数始终固定为16(比如输入32时变成32列×16行),导致单元格为矩形而非正方形。尝试修改#container的CSS Grid属性未解决问题,求排查修复。
现有代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Etch-A-Sketch.</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="title"> <h1>Etch-A-Sketch. 🖍</h1> </div> <div id="buttons"> <button id="gridsize">Size</button> <button id="rainbow">Rainbow</button> </div> <div id="container"></div> <div id="tipmessage"> <h3><em>'We don't make mistakes, just happy little accidents' - Bob Ross</em></h3> </div> </body> <script src="script.js" defer></script> </html>
CSS
#container { margin-top: 25px; display: inline-grid; grid-template-columns: repeat(16, 1fr); grid-template-rows: auto; border: 7.5px solid black; border-radius: 10px; height: 575px; width: 575px; box-sizing: border-box; } .cell { border: 1px solid black; box-sizing: border-box; } #title { display: flex; background-color: crimson; justify-content: center; width: 270px; height: 72px; margin-left: 815px; margin-top: 50px; border-style: solid aqua; border-radius: 35px; font-size: small; } #buttons { display: flex; justify-content: center; gap: 75px; margin-top: 40px; } #gridsize { background: black; color: white; border: none; width: 100px; height: 30px; font-size: large; border-radius: 20px; font-weight: bold; } #rainbow { background: black; color: white; border: none; width: 100px; font-size: large; font-weight: bold; border-radius: 20px; } #tipmessage { text-align: center; margin-top: 40px; } html { background-color: snow; text-align: center; font-family: Arial, Helvetica, sans-serif; }
JavaScript
const container = document.querySelector("#container"); const buttonSize = document.querySelector("#gridsize"); const buttonRainbow = document.querySelector("#gridsize"); let cell = document.querySelectorAll('.cell'); let cellAmount = 16; window.onload = createGrid(cellAmount); cell.onmouseover = mouseOver(); // creates a 16x16 grid function createGrid(e){ for (let i = 0; i < e*e; i++){ const div = document.createElement("div"); div.classList.add("cell"); container.appendChild(div); } } // changes cell colors to black on mouseover function mouseOver(){ let cell = document.querySelectorAll('.cell'); cell.forEach((cell) => { cell.addEventListener('mouseover', function(){ cell.style.background = "black"; }) }) } // resizes the grid and resets sketch buttonSize.addEventListener('click', () => { for (i = 0; i < cell.length; i++){ cell[i].style.removeProperty("black") } let userAmount = prompt("Select your pixel size (Default: 16)"); if (userAmount == ""){ userAmount == 16; } while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){ userAmount = prompt("Sorry, please enter a number between 4 and 100."); } cellAmount = parseInt(userAmount); while (container.hasChildNodes()){ container.removeChild(container.firstChild); } createGrid(cellAmount); mouseOver(); });
问题根源与修复方案
1. 核心问题:CSS网格配置固定
#container的grid-template-columns写死为repeat(16, 1fr),grid-template-rows设为auto,导致行数不会随单元格数量动态调整。必须通过JavaScript同步更新网格的行列配置。
2. 次要代码问题
buttonRainbow错误绑定到#gridsize按钮,应改为document.querySelector("#rainbow")window.onload = createGrid(cellAmount)会直接执行函数并赋值返回值,需改为箭头函数延迟执行cell.onmouseover = mouseOver()同理,且初始cell为空,无需这行代码- 重置颜色时
style.removeProperty("black")语法错误,应清空背景色样式
修改后的代码
JavaScript
const container = document.querySelector("#container"); const buttonSize = document.querySelector("#gridsize"); const buttonRainbow = document.querySelector("#rainbow"); let cellAmount = 16; window.onload = () => createGrid(cellAmount); // 创建对应尺寸的网格 function createGrid(size){ // 动态更新网格行列配置 container.style.gridTemplateColumns = `repeat(${size}, 1fr)`; container.style.gridTemplateRows = `repeat(${size}, 1fr)`; for (let i = 0; i < size * size; i++){ const div = document.createElement("div"); div.classList.add("cell"); container.appendChild(div); } mouseOver(); } // 鼠标悬停事件绑定 function mouseOver(){ let cells = document.querySelectorAll('.cell'); cells.forEach((cell) => { cell.removeEventListener('mouseover', handleMouseOver); cell.addEventListener('mouseover', handleMouseOver); }) } // 单独抽离事件处理函数,避免重复绑定 function handleMouseOver(){ this.style.background = "black"; } // 调整网格尺寸逻辑 buttonSize.addEventListener('click', () => { // 清空所有单元格背景色 let cells = document.querySelectorAll('.cell'); cells.forEach(cell => { cell.style.backgroundColor = ""; }); let userAmount = prompt("Select your pixel size (Default: 16)"); if (userAmount === ""){ userAmount = 16; } while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){ userAmount = prompt("Sorry, please enter a number between 4 and 100."); } cellAmount = parseInt(userAmount); // 清空容器 while (container.hasChildNodes()){ container.removeChild(container.firstChild); } createGrid(cellAmount); });
CSS(仅修改#container部分)
#container { margin-top: 25px; display: inline-grid; border: 7.5px solid black; border-radius: 10px; height: 575px; width: 575px; box-sizing: border-box; }
修改后,用户输入任意合法数值时,网格会同步设置对应行列数,单元格保持正方形,符合预期。
内容的提问来源于stack exchange,提问作者rhysez
相关产品推荐
相关产品推荐

