Javascript создает обработчик событий onClick по времени, который не замораживает страницу?

#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>