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

Sketchpad项目修改画布尺寸时出现收缩及点击失效问题求助

解决Etch-a-Sketch画布收缩与点击失效问题

问题根源

  • 画布收缩:调用getBoard时未清除原有方块,新旧方块叠加导致网格布局计算错误,视觉上表现为画布收缩
  • 点击功能失效:每次调用getBoard都会给.board添加新的点击事件监听器,多次触发后事件逻辑叠加,click状态切换混乱

修复方案

修改后的JavaScript代码

let buttons = document.querySelectorAll('[data-color]');
let buttonSize = document.querySelector('.get-size');
let buttonClear = document.querySelector('.clear');
let color = 'black';
let click = true;
let clickMessage = document.querySelector('.click-message-on');
let clickMessageOff = document.querySelector('.click-message-off');
let errorMessage = document.querySelector('.error-message');
let board = document.querySelector('.board');

buttons.forEach((button) => {
    button.addEventListener('click', function changeColor(){
        let colorSelection = button.dataset.color;
        color = colorSelection;
    })
})

buttonSize.addEventListener('click', function() {
    let size = getSize();
    if (size) getBoard(size, size);
});

buttonClear.addEventListener('click', function() {
    let squares = document.querySelectorAll('.sq');
    squares.forEach((square) => {
        square.style.backgroundColor = 'rgb(235, 135, 99)';
    })
})

function getBoard(cols, rows) {
    // 清空旧画布内容
    board.innerHTML = '';
    board.style.gridTemplateColumns = `repeat(${cols}, 1fr)`
    board.style.gridTemplateRows = `repeat(${rows}, 1fr)`
    let size = cols * rows;
    for (let i = 0; i < size; i++) {
        let fill = document.createElement('div');
        fill.className = 'sq';
        fill.addEventListener('mouseover', getColor);
        board.insertAdjacentElement('beforeend', fill);
    }
    // 替换节点清除旧事件,避免叠加
    board.replaceWith(board.cloneNode(true));
    board = document.querySelector('.board');
    // 重新绑定点击事件
    board.addEventListener('click', function() {
        click = !click;
        if (click) {
            clickMessage.textContent = 'Click enabled, you can paint! ✔️';
            clickMessageOff.textContent = '';
        } else {
            clickMessageOff.textContent = 'Click disabled, you can\'t paint! ❌';
            clickMessage.textContent = '';
        }
    })
}

function getColor() {
    if (click) {
        this.style.backgroundColor = color;
        if (color === 'random') {
        this.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 50%)`;
        }
    }
}

function getSize() {
    errorMessage.textContent = '';
    let input = prompt('Select a size');
    input = parseFloat(input);
    if (input <= 0) {
        errorMessage.textContent = 'Negative numbers are not valid!';
    } else if (input > 64) {
        errorMessage.textContent = 'Enter a number between 1 and 64';
    } else if (isNaN(input)) {
        errorMessage.textContent = 'Only numbers allowed';
    } else {
        return input;
    }
}

getBoard(32, 32);

关键修改说明

  1. 清空旧画布:在getBoard开头添加board.innerHTML = '',彻底移除原有方块,避免新旧元素叠加
  2. 解决事件叠加:通过board.replaceWith(board.cloneNode(true))替换节点,清除所有旧事件监听器,再重新绑定一次点击事件,确保逻辑唯一
  3. 优化输入处理:getSize中先清空错误信息,用isNaN更准确判断非数字输入,避免无效输入触发画布重建
  4. 减少DOM查询:提前获取.board元素,避免重复查询提升性能

效果验证

修改后点击「Select a size」按钮,输入1-64之间的有效尺寸,旧画布会被完全替换,新画布保持500x500固定尺寸,点击开关功能稳定生效,不会出现状态混乱。

内容的提问来源于stack exchange,提问作者Quickpois0n

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:10:37