如何防止Grid尺寸变化?切换边框及调单元格数时保持大小
Etch-a-Sketch 问题解决方案
一、避免切换单元格边框时Grid整体尺寸变化
边框默认会额外占用元素空间,导致Grid整体大小波动。解决核心是让边框尺寸被包含在单元格自身尺寸内,同时用透明边框替代移除边框的操作,保持元素尺寸稳定。
修改方案
- 给单元格添加
box-sizing: border-box属性,让边框计入元素宽高计算:
.box { padding: 0; /* 移除默认padding,避免干扰单元格均分 */ border: 1px solid black; box-sizing: border-box; /* 关键:边框纳入元素尺寸 */ }
- 用CSS类切换边框可见性,替代直接修改style:
.grid-border-hidden { border-color: transparent; /* 透明边框保持尺寸不变 */ }
- 调整JS边框切换逻辑:
gridBorder.addEventListener('click', function () { document.querySelectorAll('.box').forEach(box => { box.classList.toggle('grid-border-hidden'); }); });
二、实现“调整尺寸”按钮,保持Grid整体大小不变
需要给Grid设置固定宽高,调整单元格数量时先清空旧单元格,再让新单元格自动均分固定空间。
修改方案
- 给Grid设置固定宽高:
#grid { display: grid; width: 600px; /* 固定宽度 */ height: 600px; /* 固定高度 */ border: 1px solid #ccc; }
- 重构
makeGrid函数,添加清空逻辑:
function makeGrid(number) { grid.innerHTML = ''; // 清空旧单元格 grid.style.gridTemplateColumns = `repeat(${number}, 1fr)`; grid.style.gridTemplateRows = `repeat(${number}, 1fr)`; for (let i = 0; i < number * number; i++) { let cell = document.createElement('div'); cell.classList.add('box'); // 用class替代重复id,符合HTML规范 cell.classList.add('grid-border'); grid.appendChild(cell); } }
- 绑定尺寸按钮事件,添加输入验证:
size.addEventListener('click', function () { const newSize = prompt('请输入单元格数量(正整数):'); if (newSize && !isNaN(newSize) && parseInt(newSize) > 0) { makeGrid(parseInt(newSize)); bindDrawingEvents(); // 重新绑定绘图事件 // 保持边框状态一致 const isBorderHidden = document.querySelector('.box')?.classList.contains('grid-border-hidden'); if (isBorderHidden) { document.querySelectorAll('.box').forEach(box => box.classList.add('grid-border-hidden')); } } });
- 提取绘图/擦除逻辑为独立函数,避免重复绑定:
function bindDrawingEvents() { function drawColor(e) { if (e.target.classList.contains('box')) { e.target.style.backgroundColor = 'black'; } } function eraseColor(e) { if (e.target.classList.contains('box')) { e.target.style.backgroundColor = 'white'; } } // 移除旧事件,防止重复触发 grid.removeEventListener('mouseover', drawColor); grid.removeEventListener('mouseover', eraseColor); color.addEventListener('click', () => grid.addEventListener('mouseover', drawColor)); eraser.addEventListener('click', () => grid.addEventListener('mouseover', eraseColor)); }
完整修改后的代码
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" /> <title>Etch-a-Sketch</title> <link rel="stylesheet" href="style.css" /> <script src="script.js" defer></script> </head> <body> <div id="title"> <h1>Etch-a-Sketch</h1> </div> <main id="container"> <div id="menu"> <button id="size">Canvas Size</button> <button id="color">Color</button> <button id="eraser">Eraser</button> <button id="grid-borders">Grid Borders</button> </div> <div id="grid"></div> </main> </body> </html>
CSS
body { height: 100vh; } #grid { display: grid; width: 600px; height: 600px; border: 1px solid #ccc; } .box { padding: 0; border: 1px solid black; box-sizing: border-box; } .grid-border-hidden { border-color: transparent; } #title { display: flex; align-items: flex-end; justify-content: center; height: 230px; } #container { display: flex; height: 60%; width: 1204px; align-items: flex-start; justify-content: flex-end; gap: 20px; } #menu { display: flex; flex-direction: column; gap: 10px; }
JS
const grid = document.getElementById('grid'); const sizeBtn = document.getElementById('size'); const eraser = document.getElementById('eraser'); const color = document.getElementById('color'); const gridBorder = document.getElementById('grid-borders'); // 创建网格 function makeGrid(number) { grid.innerHTML = ''; grid.style.gridTemplateColumns = `repeat(${number}, 1fr)`; grid.style.gridTemplateRows = `repeat(${number}, 1fr)`; for (let i = 0; i < number * number; i++) { let cell = document.createElement('div'); cell.classList.add('box'); grid.appendChild(cell); } } // 绑定绘图与擦除事件 function bindDrawingEvents() { function drawColor(e) { if (e.target.classList.contains('box')) { e.target.style.backgroundColor = 'black'; } } function eraseColor(e) { if (e.target.classList.contains('box')) { e.target.style.backgroundColor = 'white'; } } grid.removeEventListener('mouseover', drawColor); grid.removeEventListener('mouseover', eraseColor); color.addEventListener('click', () => grid.addEventListener('mouseover', drawColor)); eraser.addEventListener('click', () => grid.addEventListener('mouseover', eraseColor)); } // 切换网格边框 gridBorder.addEventListener('click', () => { document.querySelectorAll('.box').forEach(box => box.classList.toggle('grid-border-hidden')); }); // 初始化 makeGrid(16); bindDrawingEvents(); // 尺寸调整按钮逻辑 sizeBtn.addEventListener('click', () => { const newSize = prompt('请输入单元格数量(正整数):'); if (newSize && !isNaN(newSize) && parseInt(newSize) > 0) { makeGrid(parseInt(newSize)); bindDrawingEvents(); // 继承之前的边框状态 const isHidden = document.querySelector('.box')?.classList.contains('grid-border-hidden'); if (isHidden) { document.querySelectorAll('.box').forEach(box => box.classList.add('grid-border-hidden')); } } });
内容的提问来源于stack exchange,提问作者MasterBlaster
相关产品推荐
相关产品推荐

