如何检查动态创建的按钮被单独和总共单击的频率?

How to check, how often have dynamically created buttons been clicked, individually and in total?

我创建了一个带有按钮的循环。我还创建了一个 eventListener,它为每个按钮保留一个计数。我希望当所有按钮都被按下至少 3 次时发生一些事情,所以我创建了一个 if 语句来检查计数是否为 3 并将 1 加到另一个计数,但即使按下了多个按钮,另一个计数仍保持为 1 3次。

for (let i = 0; i < 7; i++) {
  let btn = document.createElement('button');

  btn.classList.add('buttons');
  btn.id = 'button' + i;

  document.getElementById('box').appendChild(btn);

  let count = 0;
  let count2 = 0;

  btn.addEventListener('click', () => {
    count++;
    console.log(count);

    if (count === 3) {
      console.log('3');

      count2++;
      console.log(count2);
    } else {

      console.log('not 3');
    }
  });
}
#box button { min-width: 20px; min-height: 20px; }
.as-console-wrapper { max-height: 87%!important; }
body { margin: 0; }
<div class="box" id="box">
</div>

所以 count 变量工作正常,当 1 个按钮被点击 3 次时,count2 变量变为 1,但它保持在 1,我似乎无法找出原因。最后 count2 应该是 7,因为有 7 个按钮。

正如 Vladimir 在评论中暗示的那样,这是一个范围界定问题。

变量计数仅在事件侦听器内部声明,因此稍后当您按下不同的按钮时,您的代码会对不同的计数变量执行 count++

要解决此问题,请声明 var count 而不是 let count - 这将使它成为全局的。

或者在for循环之前声明计数变量。

顺便说一句:确保在 count 达到 3 时停止更新,因为它不会更新 count2 如果它达到 4 或更高

除了已经指出 OP 问题的所有评论之外,我建议基于 storing/updating 个 button-counts Map-实例中的不同方法。

通过在顶部引入 event-delegation,可以摆脱多个即时(对于每个动态创建的按钮)应用的事件处理程序,这会强制方法处理不同的计数器范围(处理程序范围和 for 块作用域).

只有一个处理程序订阅了一个 parent-node 的 'click' 事件。此处理程序通过查找单个按钮 click-count.

来跟踪和处理各种 click-count 状态

function createButton(id) {
  let elmNode = document.createElement('button');

  elmNode.classList.add('buttons');
  elmNode.id = `button${ id }`;

  return elmNode;
}
function main() {

  // keeps track of and handles the various click count states.
  function handleButtonClick({ target }) {
    const btnNode = target.closest('button');

    // update a single buttons click count total.
    const buttonClickTotal = clickCountStorage.get(btnNode) + 1;
    clickCountStorage.set(btnNode, buttonClickTotal);

    const clickCountList =  Array
      .from(
        clickCountStorage.values()
      );
    // calculate click count total of all buttons.
    const allButtonsClickTotal = clickCountList
      .reduce((total, count) => total + count, 0);

    // check whether the OP's each button minimum 3 times click applies.
    const isEveryButtonHasBeenClickedAtLeastThreeTimes = clickCountList
      .every(count => count >= 3);

    console.log({
      buttonClickTotal,
      allButtonsClickTotal,
      isEveryButtonHasBeenClickedAtLeastThreeTimes,
    });
  }
  const clickCountStorage = new Map;

  const root = document.querySelector('#box');
  // make use of event delegation ...
  // - a single eventhandler subscribed once to
  //   a single parent node's 'click' event.
  root.addEventListener('click', handleButtonClick)

  for (let elmNode, i = 0; i < 7; i++) {
    elmNode = createButton(i);

    // establish a new button reference related click count.
    clickCountStorage.set(elmNode, 0);

    root.appendChild(elmNode);
  }
} 
main();
#box button { min-width: 20px; min-height: 20px; }
.as-console-wrapper { max-height: 87%!important; }
body { margin: 0; }
<div class="box" id="box">
</div>