Etch a Sketch问题:更换网格后鼠标悬停变色功能失效
问题原因
页面初始加载时,你仅为当时存在的 .grid-item 元素绑定了鼠标悬停事件。点击按钮生成新网格后,新创建的单元格未被绑定事件,因此悬停变色功能失效。
解决方案
方案一:创建单元格时绑定事件
修改 makeGrid 函数,在每个新单元格创建时直接添加鼠标悬停事件。这样无论首次生成还是后续点击按钮生成的单元格,都会自动带上事件监听:
const container = document.getElementById('container'); function makeGrid(rows, cols) { container.style.setProperty('--gridRows', rows); container.style.setProperty('--gridColumns', cols); // 修复循环变量全局污染问题,添加let声明 for (let c = 0; c < (rows * cols); c++) { let cell = document.createElement('div'); cell.innerText = (c + 1); cell.className = 'grid-item'; // 为每个新单元格绑定悬停事件 cell.addEventListener('mouseover', () => { cell.style.background = 'blue'; }); container.appendChild(cell); } } makeGrid(6, 6); const btn = document.querySelector('button'); btn.addEventListener('click', () => { let side = prompt('Enter # of squares per side'); container.replaceChildren(); makeGrid(side, side); });
方案二:事件委托(更高效)
利用事件冒泡机制,将事件监听绑定到父容器 #container 上,而非每个单元格。这样无论何时新增单元格,只要事件冒泡到容器,就能触发处理逻辑,适合大量单元格的场景:
const container = document.getElementById('container'); function makeGrid(rows, cols) { container.style.setProperty('--gridRows', rows); container.style.setProperty('--gridColumns', cols); for (let c = 0; c < (rows * cols); c++) { let cell = document.createElement('div'); cell.innerText = (c + 1); container.appendChild(cell).className = 'grid-item'; } } makeGrid(6, 6); const btn = document.querySelector('button'); btn.addEventListener('click', () => { let side = prompt('Enter # of squares per side'); container.replaceChildren(); makeGrid(side, side); }); // 事件委托:监听容器的鼠标悬停事件 container.addEventListener('mouseover', (e) => { // 判断触发事件的元素是否为网格项 if (e.target.classList.contains('grid-item')) { e.target.style.background = 'blue'; } });
额外优化点
- 循环变量
c未声明会变成全局变量,建议添加let声明避免污染全局作用域。 - 可对用户输入的
side做合法性校验(比如限制为正整数),避免无效输入导致网格异常。
内容的提问来源于stack exchange,提问作者n00bgainz
相关产品推荐
相关产品推荐

