JS新手开发Etch-a-Sketch遇TypeError:backgroundColor非函数
问题描述
作为JavaScript新手,开发Etch-a-Sketch画板项目时遇到以下问题:
- 颜色模式激活后,鼠标划过网格div无法设置样式
- 报错信息:
TypeError: e.target.style.backgroundColor is not a function
错误原因分析
- 属性赋值错误:
backgroundColor是DOM元素的样式属性,需用赋值运算符=设置,而非函数调用(),这是报错的直接原因。 - 网格元素创建错误:仅创建了一个
gridSquare元素,循环中重复将同一个元素添加到容器,导致所有网格实际是同一个div,无法实现多格子独立交互。 - 事件绑定逻辑错误:
play函数仅给单个gridSquare绑定事件,且window.onload被两次赋值(先makeGrid()后play()),导致makeGrid可能未正确执行。 - 清空功能逻辑错误:清空按钮错误使用函数调用方式设置背景,且仅操作单个网格元素,无法清空所有格子。
修正后的代码
JavaScript代码
const colorBtn = document.getElementById('color') const shadeBtn = document.getElementById('shade') const eraseBtn = document.getElementById('erase') const clearBtn = document.getElementById('clear') const gridCont = document.getElementById('grid') let currentMode = 'color' // 默认设置为颜色模式 // 创建网格 function makeGrid() { gridCont.innerHTML = '' // 先清空容器,避免重复创建 for (let i = 0; i < 200; i++) { const gridSquare = document.createElement('div') // 每次循环创建新的div gridSquare.classList.add('gridSquare') gridCont.appendChild(gridSquare) } } // 处理网格鼠标划过事件 function handleGridMouseOver(e) { if (!e.target.classList.contains('gridSquare')) return // 确保只处理网格元素 switch(currentMode) { case 'color': e.target.style.backgroundColor = '#050505' break case 'shade': // 渐变阴影逻辑:逐步降低透明度 const currentOpacity = parseFloat(e.target.style.opacity) || 1 e.target.style.opacity = Math.max(0, currentOpacity - 0.1) e.target.style.backgroundColor = '#050505' break case 'erase': e.target.style.backgroundColor = 'white' e.target.style.opacity = 1 break } } // 清空网格 function clearGrid() { const allSquares = document.querySelectorAll('.gridSquare') allSquares.forEach(square => { square.style.backgroundColor = 'white' square.style.opacity = 1 }) } // 页面加载完成后初始化 window.addEventListener('load', () => { makeGrid() // 事件委托:给网格容器绑定事件,无需给每个格子单独绑定 gridCont.addEventListener('mouseover', handleGridMouseOver) }) // 绑定按钮事件 colorBtn.addEventListener('click', () => { currentMode = 'color' }) shadeBtn.addEventListener('click', () => { currentMode = 'shade' }) eraseBtn.addEventListener('click', () => { currentMode = 'erase' }) clearBtn.addEventListener('click', clearGrid)
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>scribblyscrabblydoo</title> <link rel="stylesheet" href="./styles.css"> </head> <body> <div class="titlebox"> <h1>sribblyscrabblydoo</h1> <p>Draw or something idk bro</p> </div> <div class="mainbod"> <div class="options"> <div class="buttons"> <h2>Options</h2> </div> <div class="buttons"> <button id="color">Color</button> </div> <div class="buttons"> <button id="shade">Shade</button> </div> <div class="buttons"> <button id="erase">Erase</button></div> <div class="buttons"> <button id="clear">Clear</button> </div> <div class="buttons"> <button id="github">Duskope Github</button> </div> </div> <div id="grid"></div> </div> </body> <script type="text/javascript" src = "index.js"></script> </html>
关键改进点
- 将
backgroundColor()改为backgroundColor =,修正属性赋值方式 - 每次循环创建新的
gridSquare元素,确保每个网格都是独立DOM节点 - 使用事件委托绑定鼠标事件,提升性能同时避免重复绑定
- 统一页面初始化逻辑,用
window.addEventListener('load')替代重复赋值window.onload - 完善清空功能,遍历所有网格元素重置样式
- 添加模式切换分支,支持颜色、阴影、擦除三种模式
内容的提问来源于stack exchange,提问作者Duskope
相关产品推荐
相关产品推荐

