首页 > 解决方案 > 为什么 for 循环中的事件处理程序不适用于所有迭代?

问题描述

使用 Vanilla JS 处理 Etch-A-Sketch 项目。我的项目遇到了一个问题,我有一个 for 循环,它创建了一个 16 * 16 网格 -

//makes a 16 x 16 grid - default grid
for(let i = 0; i < 16; i++){
    const div =  document.createElement('div');
    div.style.cssText = 'border: 1px solid black; flex: 1';
    container.appendChild(div);
    // div.addEventListener('mouseover', changeBackground);
    for (let j = 0; j < 16; j++){
        div2 = document.createElement('div');
        div2.classList.add('square');
        div.style.display = 'flex';
        div.appendChild(div2);  

        div2.addEventListener('mouseover', changeBackground);
    }
}

由 for 循环创建的网格

在内部 for 循环中,我设置了一个事件侦听器,它调用了一个回调changeBackground()- 当光标悬停在网格上时,它将随机改变颜色 - 我希望当光标移动时网格上的任何正方形都会改变颜色超过它。但是从上图中,当我将鼠标悬停在网格上时,只有网格上的最后一个正方形会改变颜色,而网格上的任何其他正方形都保持白色且无响应。所以我的问题是:为什么右下角的最后一个方格是唯一改变颜色的方格,而其他所有方格都保持空白?


function changeBackground(){
    let randomColor = colors[Math.floor(Math.random() * colors.length)];

    if(randomColor === '1'){
        div2.style.backgroundColor = 'red';
        console.log('red');
    } else if(randomColor === '2'){
        div2.style.backgroundColor = 'blue';
        console.log('blue');
    } else if(randomColor === '3'){
        div2.style.backgroundColor = 'yellow';
        console.log('yellow');
    } else if(randomColor === '4'){
        div2.style.backgroundColor = 'orange';
        console.log('orange');
    } else{
        div2.style.backgroundColor = 'green';
        console.log('green');
    }
}

标签: javascriptdom-manipulation

解决方案


您需要做的就是在changeBackground函数中获取该元素引用

function changeBackground(e){
    var div = e.target; // the current div you want to change

    // do your stuff

    div.style.backgroundColor = 'red';
}

我整理了一个快速示例来演示元素引用。它会自动传递给您的mouseover函数(我使用过button,但它适用于任何元素)并且我称之为e. 然后你需要使用 . 拉出当前元素e.target

var btns = document.getElementsByTagName('button');

for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener('mouseover', whichButton);
}

function whichButton(e) {
  var btn = e.target; // <- This is your current element (in your case, div2)
  console.log(btn);
  
  var span = document.getElementById('spanMO');
  span.textContent = btn.textContent;
}
<button>First</button><br/>
<button>Second</button><br/>
<button>Third</button><br/>

<p>
Mouseover: <span id="spanMO"></span>
</p>


推荐阅读