#javascript #html
Вопрос:
Цель: Иметь кнопку, которая при нажатии становится серой в течение 1 секунды, а после второй увеличивает значение. Это должно позволить вам выполнять другие действия на странице во время ожидания.
Проблема: Когда я нажимаю кнопку, страница зависает, и я должен дождаться завершения функции ожидания, прежде чем смогу нажать другую кнопку. Кроме того, кнопка не становится серой. Он останавливает анимацию, а затем завершает ее по истечении 1 секунды.
HTML-код:
<button id=woodBtn class=woodBtnC type="button" onClick="getWood()">Get Wood</button>
<table>
<tr>
<th>Wood</th>
</tr>
<tr>
<td id=woodValue>0</td>>
</tr>
</table>
Код Javascript:
function getWood() {
wood ;
greyOut("woodBtn", 1);
document.getElementById("woodValue").innerHTML = wood;
writeConsole("Got 1 wood!!");
}
function greyOut(id, time) {
document.getElementById(id).style.opacity = "0.5";
var start = Date.now();
do{
var now = Date.now();
var delta = now - start;
} while (delta < 1000);
document.getElementById(id).style.opacity = "1.0";
}
Я не думаю, что в javascript есть потоки, так что как мне это сделать без них?
Комментарии:
1. Взгляните на setTimeout
Ответ №1:
Измените свой greyOut
код с помощью:
function greyOut(id, time) {
document.getElementById(id).style.opacity = "0.5";
var start = Date.now();
setTimeout(function(){
document.getElementById(id).style.opacity = "1.0";
}, 1000) // delay time ms
}
Это должно сработать
Комментарии:
1. Это сработало! Спасибо тебе огромное, я был совершенно потерян. Мне нужно будет разобраться, почему этот способ работает, а другой-нет.
2. Круто, я рекомендую вам прочитать о цикле событий и тайм-аутах.
Ответ №2:
JS — это однопоточный язык, поэтому весь код выполняется только в одном потоке-вы не можете выполнять многопоточную обработку. Вы полностью потребляете поток в течение 1 секунды, когда вы ждете 1 секунду из — за непрерывного цикла-этот цикл может выполняться миллионы раз перед завершением, и вся страница замерзнет, потому что она работает непрерывно, и JS больше ничего не может сделать. Способ обработки таких случаев заключается в использовании цикла событий и функции обратного вызова — JS скажет кому-то удерживать функцию до наступления указанного события, и когда это событие произойдет, этот кто-то вернет эту функцию JS для запуска. В этом случае, если кто-то является браузером, браузер предоставляет API setTimeout
, который запускает функцию по истечении указанного времени. Вот код:
var wood = 0;
function getWood() {
wood ;
// greyOut("woodBtn", 1);
asyncGreyOut("woodBtn", 1000, function() {
document.getElementById("woodValue").innerHTML = wood;
// writeConsole("Got 1 wood!!");
console.log("Got 1 wood!!");
});
}
function asyncGreyOut(id, time, cb) {
document.getElementById(id).style.opacity = "0.5";
setTimeout(function() {
cb();
document.getElementById(id).style.opacity = "1.0";
}, time);
}
function greyOut(id, time) {
document.getElementById(id).style.opacity = "0.5";
var start = Date.now();
do {
var now = Date.now();
var delta = now - start;
} while (delta < 1000);
document.getElementById(id).style.opacity = "1.0";
}
<button id=woodBtn class=woodBtnC type="button" onClick="getWood()">
Get Wood
</button>
<table>
<tr>
<th>Wood</th>
</tr>
<tr>
<td id="woodValue">0</td>
</tr>
</table>