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

如何在JavaScript版Etch-A-Sketch中停止/移除mouseover事件(无jQuery)

问题描述

  1. 点击并鼠标移过div时能改变背景色,但释放点击后无法停止mouseover事件,无法结束绘制
  2. 点击某个div时,该div不会立即变色,必须移到旁边div才会触发变色

解决思路与代码修改

核心问题在于原事件绑定逻辑混乱,每次点击都会重复添加mouseover监听,且没有全局状态控制绘制开关。我们通过全局状态变量优化逻辑:

  • 用isDrawing标记是否处于绘制状态
  • 在mousedown时开启绘制并立即给当前点击的div上色
  • 在全局mouseup事件中关闭绘制
  • 每个网格的mouseover事件仅在isDrawing为true时执行上色操作
  • 改用Grid布局简化网格创建,避免Flex布局的错乱问题

修改后的JavaScript代码

const divCont = document.getElementById("grid-container");
let isDrawing = false; // 全局绘制状态标记

// 创建16x16网格
for (let i = 0; i < 16 * 16; i++) {
    const gridCell = document.createElement('div');
    gridCell.classList.add("secGrid");
    
    // 鼠标按下:开启绘制并立即给当前单元格上色
    gridCell.addEventListener('mousedown', () => {
        isDrawing = true;
        gridCell.style.backgroundColor = "black";
    });
    
    // 鼠标移过:仅在绘制状态下上色
    gridCell.addEventListener('mouseover', () => {
        if (isDrawing) {
            gridCell.style.backgroundColor = "black";
        }
    });
    
    divCont.appendChild(gridCell);
}

// 全局监听鼠标抬起:停止绘制
document.addEventListener('mouseup', () => {
    isDrawing = false;
});

修改后的CSS代码

* {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

#grid-container {
    display: grid;
    grid-template-columns: repeat(16, 1fr);
    grid-template-rows: repeat(16, 1fr);
    width: 80vh;
    height: 80vh;
    margin: 20px auto;
    gap: 1px;
    background-color: black;
}

.secGrid {
    background-color: yellow;
}

关键修改说明

  • 用isDrawing状态变量替代重复绑定/移除事件的复杂操作,逻辑更简洁
  • 替换click为mousedown事件,解决点击当前div不立即上色的问题
  • 全局绑定mouseup,确保鼠标在任意位置释放都能停止绘制
  • 改用Grid布局创建网格,比Flex更适配行列对齐的需求,避免原布局的错乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:15:40