Javascript 无法理解脚本停止工作的原因。

Javascript 无法理解脚本停止工作的原因。,javascript,Javascript,我正在制作一个简单的蚀刻草图程序。我有两个按钮。1重置屏幕,另一个创建新屏幕,并允许您选择绘图区域中的像素数。默认大小起作用,重置起作用。当我单击“新建”按钮并设置绘图区域中的像素数时,会更新eventlistener,但eventlistener停止工作,鼠标移到上面不会再更改div的背景色。这是我的密码: const screen = document.querySelector('.screen') const clearButton = document.querySelector('.

我正在制作一个简单的蚀刻草图程序。我有两个按钮。1重置屏幕,另一个创建新屏幕,并允许您选择绘图区域中的像素数。默认大小起作用,重置起作用。当我单击“新建”按钮并设置绘图区域中的像素数时,会更新eventlistener,但eventlistener停止工作,鼠标移到上面不会再更改div的背景色。这是我的密码:

const screen = document.querySelector('.screen')
const clearButton = document.querySelector('.clear-btn');
const newButton = document.querySelector('.new-btn');
var size = 64;

function createGrid(size) {
  document.styleSheets[0].cssRules[3].style["grid-template-columns"] = "repeat(" + size + ", 1fr)"
  document.styleSheets[0].cssRules[3].style["grid-template-rows"] = "repeat(" + size + ", 1fr)"
  console.log('createGrid');
  for (i = 0; i < size*size; i++) { 
    const grid = document.createElement('div');
    grid.classList.add('grid');
    grid.style.cssText = 'color: #cccccc; background: #cccccc; border: solid 1px lightgrey;';      
    screen.appendChild(grid);
  }
}

function reset() {
  for (i = 0; i < size*size; i++) { 
  grid[i].style.backgroundColor = "#cccccc";
  }
}

function newSize(){
  let userResponse = prompt("Please enter size of canvas: ", "");
  size = parseInt(userResponse);
  remove();
  createGrid(size);
}


function remove(){
  while (screen.firstChild) {
    console.log(size);
    screen.removeChild(screen.firstChild);
  }
}

createGrid(size);

clearButton.addEventListener('click', reset);
newButton.addEventListener('click', newSize);

var grid = document.getElementsByClassName('grid');
Array.from(grid).forEach((tile) => {
  tile.addEventListener('mouseover', (e) => {
    e.target.style.background = '#0d0d0d';

  });
})

const screen=document.querySelector(“.screen”)
const clearButton=document.querySelector('.clear btn');
const newButton=document.querySelector('.new btn');
变量大小=64;
函数createGrid(大小){
document.styleSheets[0]。cssRules[3]。样式[“网格模板列”]=“重复(“+size+”,1fr)”
document.styleSheets[0]。cssRules[3]。样式[“网格模板行”]=“重复(“+size+”,1fr)”
log('createGrid');
对于(i=0;i{
tile.addEventListener('mouseover',(e)=>{
e、 target.style.background='#0d0d';
});
})

创建网格时,需要添加事件侦听器。删除网格,该网格已附加事件原始事件侦听器,而新创建的网格未附加任何内容:

function createGrid(size) {
  document.styleSheets[0].cssRules[3].style["grid-template-columns"] = "repeat(" + size + ", 1fr)"
  document.styleSheets[0].cssRules[3].style["grid-template-rows"] = "repeat(" + size + ", 1fr)"
  console.log('createGrid');
  for (i = 0; i < size*size; i++) { 
    const grid = document.createElement('div');
    grid.classList.add('grid');
    grid.style.cssText = 'color: #cccccc; background: #cccccc; border: solid 1px lightgrey;';      
    screen.appendChild(grid);

    // Add listener to grid cell
    grid.addEventListener('mouseover', (e) => {
       e.target.style.background = '#0d0d0d';
    })
  }
}
函数createGrid(大小){
document.styleSheets[0]。cssRules[3]。样式[“网格模板列”]=“重复(“+size+”,1fr)”
document.styleSheets[0]。cssRules[3]。样式[“网格模板行”]=“重复(“+size+”,1fr)”
log('createGrid');
对于(i=0;i{
e、 target.style.background='#0d0d';
})
}
}

您还可以查看一下,这样就不必为每个单元格添加侦听器,而可以将其添加到容器中。

原因是您现在有了新的div。您的侦听器已附加到原始HTMLNodes,现在您添加了新的侦听器,它们没有附加任何侦听器。解决办法是: -清理旧的侦听器(在remove函数中) -附加新侦听器(在newSize函数中)

将最后一部分(从
var grid=document.getElementsByClassName…
)移动到函数中,并在新大小函数的末尾调用它,如下所示:

function atachListeners() {
  const grid = document.getElementsByClassName('grid');
  Array.from(grid).forEach(tile => {
    tile.addEventListener('mouseover', ...);
  });
};
function newSize(){
  let userResponse = prompt("Please enter size of canvas: ", "");
  size = parseInt(userResponse);
  remove();
  createGrid(size);
  attachListeners();
}
现在,您的newSize函数如下所示:

function atachListeners() {
  const grid = document.getElementsByClassName('grid');
  Array.from(grid).forEach(tile => {
    tile.addEventListener('mouseover', ...);
  });
};
function newSize(){
  let userResponse = prompt("Please enter size of canvas: ", "");
  size = parseInt(userResponse);
  remove();
  createGrid(size);
  attachListeners();
}
移除得到的是加法:

function remove() {
  removeTileListeners();
  while (screen.firstChild) {        
    screen.removeChild(screen.firstChild);
  } 
}

实现RemovelListeners()方法后,我留给您作为家庭作业:)

没问题。请确保删除每个新图形上的侦听器,否则它们将保持活动状态,这将导致内存泄漏。通过事件委派,他根本不必删除父容器,也不必担心如何管理侦听器。。。同意删除侦听器是一个好习惯,但认为现代浏览器在管理这方面做得很好。如果要进行最佳实践和内存管理,事件委派似乎是不需要动脑筋的。是的,委派肯定会有帮助,特别是在OPs侦听器计数方面。而且取消订阅是必须的,否则OP会开始抱怨“现在浏览器占用了20 Gig的内存”,就像我昨天在社交媒体上看到的:)