如何实现点击按钮调整Etch a Sketch网格尺寸且避免重复创建?
解决Etch-A-Sketch网格重复创建问题
问题核心:点击网格尺寸按钮时,没有清除容器内已有的方块,直接添加新方块导致网格叠加混乱;同时每次切换网格都重复绑定鼠标事件,会导致颜色触发多次。
修复步骤:
- 创建新网格前清空容器
在创建新方块前,先清空容器内所有旧元素,避免新旧方块叠加。 - 使用事件委托优化鼠标事件绑定
把mouseover事件绑定到容器上,利用事件冒泡机制处理方块颜色变化,只需要绑定一次,无论网格怎么切换都有效,还能避免重复绑定导致的多次触发问题。 - 简化颜色切换逻辑
直接修改全局颜色变量,事件委托的回调会自动使用最新的颜色值,无需每次切换都重新绑定事件。
修改后的完整代码
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="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Neucha&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <title>Etch-A-Sketch</title> </head> <body> <h1>Etch-A-Sketch</h1> <div class="options"> <button class="reset">Reset</button> <button class="eraser">Eraser</button> <button class="randomColor" title="Selects a random color for you">Color</button> <nav> <ul class="drop-down closed"> <li><a href="#" id="nav-button">Grid size</a></li> <li><a href="#" id="sixteen">16 x 16</a></li> <li><a href="#" id="thirty">32 x 32</a></li> <li><a href="#" id="sixty">64 x 64</a></li> </ul> </nav> </div> <div class="container"></div> <script src="main.js"></script> </body> </html>
CSS(无修改)
h1 { text-align: center; font-family: Neucha, sans-serif; } .container { margin: 1em auto 0; height: 500px; width: 500px; box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, rgba(0, 0, 0, 0.22) 0px 15px 12px; } .square { border: 1px solid rgba(97, 150, 255, 0.567); } div.options { display: flex; justify-content: center; align-items: center; } button { height: 42px; width: 90px; background-color: #fff; border-radius: 15px 225px 255px 15px 15px 255px 225px 15px; border-style: solid; border-width: 2px; box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px; color: black; cursor: pointer; font-family: Neucha, sans-serif; font-size: 1rem; transition: all 235ms ease-in-out; border-bottom-left-radius: 15px 255px; border-bottom-right-radius: 225px 15px; border-top-left-radius: 255px 15px; border-top-right-radius: 15px 225px; margin-right: 15px; } button:hover { box-shadow: rgba(0, 0, 0, .3) 2px 8px 8px -5px; transform: translate3d(0, 2px, 0); } button:focus { box-shadow: rgba(0, 0, 0, .3) 2px 8px 4px -6px; } nav .drop-down { overflow: hidden; height: 172px; width: 130px; line-height: 30px; text-align: center; -webkit-transition: height 0.3s ease; transition: height 0.3s ease; background-color: #fff; border-radius: 15px 225px 255px 15px 15px 255px 225px 15px; border-style: solid; border-width: 2px; padding: 0; box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px; color: black; cursor: pointer; font-family: Neucha, sans-serif; font-size: 1rem; transition: all 235ms ease-in-out; border-bottom-left-radius: 15px 255px; border-bottom-right-radius: 225px 15px; border-top-left-radius: 255px 15px; border-top-right-radius: 15px 225px; touch-action: manipulation; list-style: none; } nav .drop-down.closed { height: 38px; } nav .drop-down li { border-bottom: 2px solid black; } nav .drop-down li a { display: block; color: black; text-decoration: none; padding: 6px; } nav .drop-down li:first-child a:after { content: "\25BC"; float: right; margin-left: -30px; margin-right: 5px; }
JavaScript(核心修改部分)
const container = document.querySelector('.container') const eraser = document.querySelector('.eraser') const randomColorBtn = document.querySelector('.randomColor') const sixteenBtn = document.getElementById('sixteen') const thirtyBtn = document.getElementById('thirty') const sixtyBtn = document.getElementById('sixty') const resetBtn = document.querySelector('.reset') // 重置按钮 resetBtn.addEventListener('click', () => location.reload()); // 全局颜色变量 let bgColor = 'black'; // 事件委托 - 只绑定一次鼠标划过事件 container.addEventListener('mouseover', (e) => { if (e.target.classList.contains('square')) { e.target.style.backgroundColor = bgColor; } }); // 创建网格函数:先清空容器,再创建新方块 function squaresCreator(numSquares) { // 清空容器内所有旧方块 container.innerHTML = ''; // 设置网格布局 container.style.display = "grid"; container.style.gridTemplateRows = `repeat(${numSquares}, 1fr)`; container.style.gridTemplateColumns = `repeat(${numSquares}, 1fr)`; // 创建新方块 const totalSquares = numSquares * numSquares; for (let i = 0; i < totalSquares; i++) { const div = document.createElement('div') div.classList.add('square'); container.appendChild(div); } } // 初始化默认网格 squaresCreator(16); // 橡皮擦功能 eraser.addEventListener("click", function() { bgColor = 'white'; }); // 随机颜色功能 const colorArray = [ "AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGrey", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange", "DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkSlateGrey", "DarkTurquoise", "DarkViolet", "DeepPink", "DeepSkyBlue", "DimGray", "DimGrey", "DodgerBlue", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Grey", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow", "LightGray", "LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSlateGrey", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid", "PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "RebeccaPurple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "SlateGrey", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen" ]; randomColorBtn.addEventListener("click", function() { bgColor = colorArray[Math.floor(Math.random() * colorArray.length)]; }); // 下拉菜单切换 (function() { document.querySelector('#nav-button').addEventListener('click', function() { this.parentNode.parentNode.classList.toggle('closed') }, false); })(); // 网格尺寸按钮事件 sixteenBtn.addEventListener("click", function() { squaresCreator(16); }) thirtyBtn.addEventListener("click", function() { squaresCreator(32); }) sixtyBtn.addEventListener("click", function() { squaresCreator(64); })
内容的提问来源于stack exchange,提问作者Franco Canzani
相关产品推荐
相关产品推荐

