Я создал петлю с кнопками в ней. Я также создал прослушиватель событий, который ведет подсчет для каждой кнопки. Я хочу, чтобы что-то произошло, когда все кнопки были нажаты не менее 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 кнопок.
Каждый клик увеличивает count
. Когда оно достигает ровно 3, вы увеличиваете count2
. Это больше никогда не повторится, потому что следующий щелчок увеличивает count
до 4. Пожалуйста, уточните, как именно вы хотите, чтобы это работало, потому что из вашего описания кажется, что вам понадобится отдельная переменная счетчика для каждой кнопки.
@VladimirKornea Когда я изменил его для обоих, отдельные счетчики исчезли для всех кнопок, но теперь, когда я изменил его только для 2-го, он работает отлично!
@ChrisG Он автоматически создает отдельные счетчики для всех кнопок (вероятно, это как-то связано с let, потому что, если я изменю его на var, это больше не будет)
Итак, count2 должен подсчитывать количество кнопок, достигших count == 3 или более? Это работает, но использование let
внутри {} создает независимую переменную для каждого блока (замыкания). В идеале вы должны переместить let count2
за пределы цикла for над своим кодом.
как Владимир намекнул в комментариях, это проблема масштаба.
Переменная count объявляется только внутри прослушивателя событий, поэтому позже, когда вы нажимаете другую кнопку, ваш код делает count++
для другой переменной count.
Чтобы решить эту проблему, объявите var count
вместо let count
- это сделает ее глобальной.
Или объявите переменную count перед циклом for
.
Кстати: не забудьте прекратить обновление count
, когда оно достигнет 3, так как оно не будет обновляться count2
, если оно достигнет 4 или выше.
Да, я использовал его, и он отлично работает! Я обновлю его, чтобы он больше не обновлял счетчик
В дополнение ко всем комментариям, которые уже указывали на проблему ОП, я предлагаю другой подход, основанный на сохранении/обновлении отдельных счетчиков кнопок в экземпляре 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>
Что произойдет, если вы замените
let
наvar
для подсчета?