Etch-a-Sketch重置按钮失效:JavaScript点击事件无响应
我是Stack Overflow新手,已经花了很多时间查找相关问题但没找到解决方案。我的项目用JavaScript操作DOM,其他功能都正常,但重置按钮完全没反应,控制台也没有报错。我加了console.log测试按钮,确认按钮能被触发,但重置功能就是不生效。
我怀疑是不是reset函数和createGrid循环有关联?我试过移除HTML里的onclick,给resetButton加addEventListener调用reset函数,但报错;也试过在循环里加事件监听器,同样报错。除非操作有误,否则我觉得没必要把重置逻辑放进createGrid函数里。
以下是我的代码:
JavaScript代码
let color = "black"; //Waits for everything to load, then creates default grid size document.addEventListener("DOMContentLoaded", () => { createGrid(16); }); const mainContainer = document.querySelector('.main-container'); mainContainer.stlye = ('display: flex; flex-wrap: wrap; justify-content: center; align-items: center;'); const headerContainer = document.querySelector('.header'); mainContainer.appendChild(headerContainer); headerContainer.style = ('margin-top: 20px') const headerP = document.createElement("p"); headerContainer.appendChild(headerP); headerP.textContent = 'Choose how many squares you would like in your canvas (2 = 2x2 to maximum 100 = 100x100)'; headerP.style = ('margin-bottom: 10px'); const gridInput = document.createElement("input"); gridInput.setAttribute('type', 'number'); gridInput.setAttribute('max', '100'); gridInput.setAttribute('min', '2'); gridInput.style = ('width: 50px; margin-right: 20px'); headerContainer.appendChild(gridInput); const inputButton = document.createElement("button"); inputButton.textContent = 'Submit'; inputButton.setAttribute('class', 'btn btn-info'); inputButton.style = ('padding: 3px'); headerContainer.appendChild(inputButton); let canvasContainer = document.querySelector('.canvas-container'); canvasContainer.style = ('height: 600px; width: 600px; display: grid; border: 1px solid black; margin-top: 20px;'); mainContainer.appendChild(canvasContainer); const footerContainer = document.querySelector('.footer'); footerContainer.style = ('display: flex; justify-content: center; margin-top: 20px') mainContainer.appendChild(footerContainer); const eraseButton = document.getElementsByClassName('.btn btn-secondary'); const resetButton = document.getElementsByClassName('.btn btn-warning'); const randomColorButton = document.getElementsByClassName('.btn btn-primary'); //Grid size creation funcion that creates divs in a defined size from a loop and appends it into the grid/canvas container const createGrid = (num) => { canvasContainer.style.gridTemplateColumns = `repeat(${num}, 1fr)` canvasContainer.style.gridTemplateRows = `repeat(${num}, 1fr)` let numDivs = num * num; for(let i = 0; i < numDivs; i++) { let gridDiv = document.createElement('div.canvas'); canvasContainer.appendChild(gridDiv); gridDiv.addEventListener('mouseover', () => { //event listener that changes background color depending on which button is selected if(color == "random") { let randomR = Math.floor(Math.random() * 256) let randomG = Math.floor(Math.random() * 256) let randomB = Math.floor(Math.random() * 256) gridDiv.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`; } else if(color == "white") { gridDiv.style.backgroundColor = 'white'; } else { gridDiv.style.backgroundColor = 'black'; } }) canvasContainer.insertAdjacentElement('beforeend', gridDiv) }; }; const colorize = (colorChoice) => { color = colorChoice; } //Input button to change the grid size based on the input box inputButton.addEventListener('click', () => { let gridSize = createGrid(gridInput.value); createGrid(gridSize); }); const reset = () => { let squares = document.querySelectorAll("div") squares.forEach((div) => div.style.backgroundColor = 'white') };
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="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href=styles.css> </head> <body> <h1>Etch-a-Sketch</h1> <div class="main-container"> <div class="header"></div> <div class="canvas-container"></div> <div class="footer"> <button class="btn btn-secondary" id="erase" onclick="colorize('white')">Eraser</button> <button class="btn btn-danger" id="reset" onclick="reset()">Clear Board</button> <button class="btn btn-dark" id="black" onclick="colorize('black')">Black Color</button> <button class="btn btn-primary" id="random" onclick="colorize('random')">Random Colors</button> </div> </div> <script src="scripts.js" defer></script> </body> </html>
问题分析与修复
- reset函数选中范围错误
你的reset函数用document.querySelectorAll("div")选中了页面上所有div,包括header、footer等无关元素,干扰了网格元素的重置效果。应该只选中canvas-container内的网格div:
const reset = () => { let squares = canvasContainer.querySelectorAll("div") squares.forEach((div) => div.style.backgroundColor = 'white') };
- createGrid中元素创建错误
document.createElement('div.canvas')是错误语法,createElement的参数只能是标签名,添加类名需要用classList:
let gridDiv = document.createElement('div'); gridDiv.classList.add('canvas'); // 添加类名
重复添加网格元素
createGrid里同时调用了appendChild和insertAdjacentElement,属于冗余操作,保留其中一个即可,比如只保留canvasContainer.appendChild(gridDiv);。输入按钮逻辑错误
当前输入按钮的点击事件中,createGrid没有返回值,导致gridSize为undefined,进而调用createGrid(undefined)产生错误。同时创建新网格前未清空旧网格,会导致新旧网格叠加:
inputButton.addEventListener('click', () => { const size = parseInt(gridInput.value); // 验证输入合法性 if (!isNaN(size) && size >= 2 && size <= 100) { canvasContainer.innerHTML = ''; // 清空旧网格 createGrid(size); } });
拼写错误
mainContainer.stlye应为mainContainer.style,拼写错误会导致样式不生效。getElementsByClassName用法错误
document.getElementsByClassName('.btn btn-secondary')不需要加.,针对带id的按钮,更推荐用querySelector通过id获取,定位更准确:
const eraseButton = document.querySelector('#erase'); const resetButton = document.querySelector('#reset'); const randomColorButton = document.querySelector('#random');
内容的提问来源于stack exchange,提问作者user22512633

