元素事件侦听器影响其他元素

Element event listener affects other element

我在用户点击时添加 divs。 如果用户单击令人兴奋的 div 我希望它改变颜色。 然而不知何故,受影响的 div 总是最后一个附加的。我怎样才能让受压者 div 成为受影响的人?

document.addEventListener('click', e =>{
    el=document.createElement('div')
    document.body.appendChild(el)
    el.style.left = e.clientX-25 + 'px'
    el.style.top = e.clientY-25 + 'px'
    el.addEventListener('click', e =>{
      el.style.backgroundColor = 'green'
    })
})
div {
    width:50px;
    height:50px;
    background-color:blue;
    border: 1px solid black;
    position:absolute;
}
<html>
    <body>
        click to make two different squres. then click again on the first squre you created.
    </body>
</html>

尝试 运行 此代码,单击以创建两个正方形,然后再次单击您的第一个正方形。为什么第二个要变色?

您在此处隐式创建了一个名为 el 的全局变量:

el=document.createElement('div')

当您点击一个正方形时,点击侦听器将 运行 并执行:

el.style.backgroundColor = 'green'

这将查找 el 当前引用的内容并更改其样式。但是 el 是全局的,每次点击(并创建一个正方形)时都会重新分配。因此,无论何时您单击 任何 个方块,创建的 last 方块将始终是更改其样式的方块。

声明 el 以便它只作用于函数,而不是全局。

document.addEventListener('click', e => {
  const el = document.createElement('div')
  document.body.appendChild(el)
  el.style.left = e.clientX - 25 + 'px'
  el.style.top = e.clientY - 25 + 'px'
  el.addEventListener('click', e => {
    el.style.backgroundColor = 'green'
  })
})
div {
  width: 50px;
  height: 50px;
  background-color: blue;
  border: 1px solid black;
  position: absolute;
}
<html>

<body>
  click to make two different squres. then click again on the first squre you created.
</body>

</html>

我强烈建议使用 ESLint 及其 no-undef 规则来帮助自己避免犯此类错误。

如果您点击现有的方块,您可能还不想创建方块 - 相反,仅更改现有方块的颜色。如果这是您想要的,请阻止事件传播。

document.addEventListener('click', e => {
  const el = document.createElement('div')
  document.body.appendChild(el)
  el.style.left = e.clientX - 25 + 'px'
  el.style.top = e.clientY - 25 + 'px'
  el.addEventListener('click', e => {
    // don't let the event bubble up to the click listener above
    e.stopPropagation();
    el.style.backgroundColor = 'green'
  })
})
div {
  width: 50px;
  height: 50px;
  background-color: blue;
  border: 1px solid black;
  position: absolute;
}
<html>

<body>
  click to make two different squres. then click again on the first squre you created.
</body>

</html>