#javascript #html #button #boolean #progress-bar
#javascript #HTML #кнопка #логическое #индикатор выполнения
Вопрос:
Мне интересно, как я мог бы остановить нажатие кнопки, если функция, которую она выполняет, запущена. Вот мой JS-код:
let money = 0;
let running = false;
function start(time, val) {
if (running == false) {
running = true;
console.log(running)
let bar = document.getElementById('progressBar1');
bar.value = time;
time ;
let sim = setTimeout("start(" time ")", 30);
if (time == 100) {
bar.value = 0;
let id = val;
money ;
document.getElementById("moneyValue").innerHTML = money;
clearTimeout(sim);
running = false;
}
} else if (running == true) {
console.log("Already Growing!");
};
}
<progress id="progressBar1" value="0" max="100" style="width:150px;"></progress>
<button id="restart-button" class="plantBtn" onclick="start(0, this.id)">Plant Seed</button>
Что он делает, так это запускает индикатор выполнения (progress div). Я хочу, чтобы кнопка предупреждала о сообщении, в котором говорится, что оно уже запущено или что-то в этом роде.
Проблема, с которой я сталкиваюсь, заключается в том, что он переходит к оператору else if и ничего не запускает. Странно то, что если я добавлю a console.log
в середину оператора if, это сработает.
Я думаю, это связано с тем, что для заполнения панели требуется время, она никогда не будет заполнена, если пользователь нажмет на нее, потому что она перейдет к оператору else if и отменит функцию if. (Он снова становится false только после того, как панель достигает 100%)
Кто-нибудь может помочь? Я открыт для JS или Jquery (немного ржавый на этом).
Спасибо
Комментарии:
1. У вас есть дополнительная фигурная скобка; вместо
} else if (running == true) {
того, чтобы вам просто нужноelse if (running == true) {
2. Нет, эта фигурная скобка связана с другим оператором if (внутри первого)
3. Почему вы вызываете ту же функцию? Код после тайм-аута должен вызываться с тайм-аутом, а не вызывать логику, которая его запускает
4. что? Это происходит каждый раз, когда нажимается кнопка. Таким образом, кнопка будет нажата несколько раз, но я не хочу, чтобы она выполняла действие до завершения предыдущего
5. @epascarello не могли бы вы продемонстрировать?
Ответ №1:
Вам нужно запретить нажатие кнопки, а не фактическую start
функцию, из которой вам нужно вызвать ее по таймеру. Поэтому лучше разделить эти функции:
let money = 0;
let running = false;
// when clicking the button
function onClickButton(time, val) {
if(running) {
console.log("Already Growing!");
} else {
running = true;
start(time, val);
}
}
// timer function
function start(time, val) {
let bar = document.getElementById('progressBar1');
bar.value = time;
time ;
let sim = setTimeout(() => start(time), 30);
if (time == 100) {
bar.value = 0;
let id = val;
money ;
document.getElementById("moneyValue").innerHTML = money;
clearTimeout(sim);
running = false;
}
}
#moneyValue::before {
content: 'Money: ';
}
<div id="moneyValue">0</div>
<progress id="progressBar1" value="0" max="100" style="width:150px;"></progress>
<button id="restart-button" class="plantBtn" onclick="onClickButton(0, this.id)">Plant Seed</button>
Ответ №2:
Выделите логику в другую функцию, которая выполняет обновление. Кнопка, которая запускает ее в одном методе, и логика, которая обновляет пользовательский интерфейс в другом.
let money = 0;
let running = false;
function start(time, val) {
if (running == false) {
running = true;
console.log(running)
runIt(time, val);
} else if (running == true) {
console.log("Already Growing!");
};
}
function runIt(time, val) {
let bar = document.getElementById('progressBar1');
bar.value = time;
time ;
let sim = setTimeout(function () {runIt(time); }, 30);
if (time == 100) {
bar.value = 0;
let id = val;
money ;
document.getElementById("moneyValue").innerHTML = money;
running = false;
}
}
<progress id="progressBar1" value="0" max="100" style="width:150px;"></progress>
<button id="restart-button" class="plantBtn" onclick="start(0, this.id)">Plant Seed</button>
<div id="moneyValue"></div>
Ответ №3:
Вы могли бы добавить дополнительный параметр, который сообщает функции, что вызов исходит из цикла, и не нужно проверять, запущен ли он уже.
let money = 0;
let running = false;
function start(time, val, isFromTimer) {
if (running == false || isFromTimer == true) { // add check
running = true;
console.log(running)
let bar = document.getElementById('progressBar1');
bar.value = time;
time ;
let sim = setTimeout(() => start(time, val, true), 30); // tell function it's from the timer
if (time >= 100) { // use more than or equal to instead
bar.value = 0;
let id = val;
money ;
//document.getElementById("moneyValue").innerHTML = money;
clearTimeout(sim);
running = false;
}
} else if (running == true) {
console.log("Already Growing!");
};
}
<progress id="progressBar1" value="0" max="100" style="width:150px;"></progress>
<button id="restart-button" class="plantBtn" onclick="start(0, this.id)">Plant Seed</button>
Ответ №4:
Почему бы вам просто не использовать некоторые манипуляции с CSS в своей функции после нажатия на нее?
document.getElementById('restart-button').disabled = true;
Затем в конце вашей функции:
document.getElementById('restart-button').disabled = false;