Как проверить, как часто нажимались динамически созданные кнопки, по отдельности и в целом?

Я создал петлю с кнопками в ней. Я также создал прослушиватель событий, который ведет подсчет для каждой кнопки. Я хочу, чтобы что-то произошло, когда все кнопки были нажаты не менее 3 раз, поэтому я создал оператор if, который проверяет, равен ли счетчик 3, и добавляет 1 к другому счетчику, но другой счетчик остается равным 1, даже если было нажато несколько кнопок. три раза.

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 кнопок.

Что произойдет, если вы замените let на var для подсчета?

Vladimir Kornea 17.05.2022 14:34

Каждый клик увеличивает count. Когда оно достигает ровно 3, вы увеличиваете count2. Это больше никогда не повторится, потому что следующий щелчок увеличивает count до 4. Пожалуйста, уточните, как именно вы хотите, чтобы это работало, потому что из вашего описания кажется, что вам понадобится отдельная переменная счетчика для каждой кнопки.

Chris G 17.05.2022 14:38

@VladimirKornea Когда я изменил его для обоих, отдельные счетчики исчезли для всех кнопок, но теперь, когда я изменил его только для 2-го, он работает отлично!

TLausie 17.05.2022 14:39

@ChrisG Он автоматически создает отдельные счетчики для всех кнопок (вероятно, это как-то связано с let, потому что, если я изменю его на var, это больше не будет)

TLausie 17.05.2022 14:42

Итак, count2 должен подсчитывать количество кнопок, достигших count == 3 или более? Это работает, но использование let внутри {} создает независимую переменную для каждого блока (замыкания). В идеале вы должны переместить let count2 за пределы цикла for над своим кодом.

Chris G 17.05.2022 14:42
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
1
5
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

как Владимир намекнул в комментариях, это проблема масштаба.

Переменная count объявляется только внутри прослушивателя событий, поэтому позже, когда вы нажимаете другую кнопку, ваш код делает count++ для другой переменной count.

Чтобы решить эту проблему, объявите var count вместо let count - это сделает ее глобальной.

Или объявите переменную count перед циклом for.

Кстати: не забудьте прекратить обновление count, когда оно достигнет 3, так как оно не будет обновляться count2, если оно достигнет 4 или выше.

Да, я использовал его, и он отлично работает! Я обновлю его, чтобы он больше не обновлял счетчик

TLausie 17.05.2022 14:51

В дополнение ко всем комментариям, которые уже указывали на проблему ОП, я предлагаю другой подход, основанный на сохранении/обновлении отдельных счетчиков кнопок в экземпляре Map.

С введением event-делегация сверху можно было бы избавиться от множества применяемых «на лету» (для каждой динамически создаваемой кнопки) обработчиков событий, которые заставляют подход работать с разными областями счетчика (область обработчика и область блока for).

Будет ровно один обработчик, подписанный один раз на 'click'-событие одного родительского узла. Этот обработчик отслеживает и обрабатывает различные состояния количества кликов, просматривая количество кликов отдельных кнопок.

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>

Другие вопросы по теме