You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击按钮调整Etch a Sketch网格尺寸且避免重复创建?

解决Etch-A-Sketch网格重复创建问题

问题核心:点击网格尺寸按钮时,没有清除容器内已有的方块,直接添加新方块导致网格叠加混乱;同时每次切换网格都重复绑定鼠标事件,会导致颜色触发多次。

修复步骤:

  1. 创建新网格前清空容器
    在创建新方块前,先清空容器内所有旧元素,避免新旧方块叠加。
  2. 使用事件委托优化鼠标事件绑定
    把mouseover事件绑定到容器上,利用事件冒泡机制处理方块颜色变化,只需要绑定一次,无论网格怎么切换都有效,还能避免重复绑定导致的多次触发问题。
  3. 简化颜色切换逻辑
    直接修改全局颜色变量,事件委托的回调会自动使用最新的颜色值,无需每次切换都重新绑定事件。

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 06:55:16