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

JS新手开发Etch-a-Sketch遇TypeError:backgroundColor非函数

问题描述

作为JavaScript新手,开发Etch-a-Sketch画板项目时遇到以下问题:

  • 颜色模式激活后,鼠标划过网格div无法设置样式
  • 报错信息:TypeError: e.target.style.backgroundColor is not a function
错误原因分析
  1. 属性赋值错误:backgroundColor是DOM元素的样式属性,需用赋值运算符=设置,而非函数调用(),这是报错的直接原因。
  2. 网格元素创建错误:仅创建了一个gridSquare元素,循环中重复将同一个元素添加到容器,导致所有网格实际是同一个div,无法实现多格子独立交互。
  3. 事件绑定逻辑错误:play函数仅给单个gridSquare绑定事件,且window.onload被两次赋值(先makeGrid()后play()),导致makeGrid可能未正确执行。
  4. 清空功能逻辑错误:清空按钮错误使用函数调用方式设置背景,且仅操作单个网格元素,无法清空所有格子。
修正后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:54:26