Przyciski uruchamiania i zatrzymywania timera w JavaScript

Stwórzmy teraz dwa przyciski: po naciśnięciu pierwszego niech timer się uruchamia, a po naciśnięciu drugiego - zatrzymuje. Tutaj sprawa nie będzie już taka prosta i czeka na nas pułapka. Aby zrozumieć istotę tej pułapki, opiszmy tworzenie kodu krok po kroku.

A więc, robimy dwa przyciski:

html<button id="start">start</button>
<button id="stop">stop</button>

Pobieramy referencje do tych przycisków do zmiennych:

javascriptlet start = document.querySelector('#start');
let stop  = document.querySelector('#stop');

Po naciśnięciu pierwszego przycisku uruchamiamy timer, zapisując jego numer w zmiennej:

javascriptstart.addEventListener('click', function() {
  let timerId = setInterval(function() {
    console.log('!')
  }, 1000);
});

A teraz zatrzymajmy timer po naciśnięciu drugiego przycisku:

javascriptstart.addEventListener('click', function() {
  let timerId = setInterval(function() {
    console.log('!')
  }, 1000);
});

// Zatrzymujemy timer:
stop.addEventListener('click', function() {
  clearInterval(timerId);
});

Jednakże, jeśli spróbujemy uruchomić powyższy kod, czeka nas niespodzianka: przy próbie zatrzymania timera okaże się, że zmienna timerId jest równa undefined! Dlaczego tak się stało? Ponieważ przy uruchamianiu timera uczyniliśmy naszą zmienną timerId lokalną wewnątrz funkcji powiązanej z przyciskiem start.

Dla rozwiązania problemu uczynmy zmienną timerId globalną - w tym przypadku będzie ona dostępna zarówno w funkcji uruchamiania timera, jak i w funkcji jego zatrzymywania:

javascriptlet timerId; // uczynmy zmienną globalną

start.addEventListener('click', function() {
  timerId = setInterval(function() {
    console.log('!')
  }, 1000);
});

stop.addEventListener('click', function() {
  clearInterval(timerId);
});
Задание 1

Niech będzie dana zmienna, w której początkowo przechowywana jest liczba 100. Dane są także dwa przyciski. Po naciśnięciu pierwszego przycisku uruchom timer, który co sekundę będzie zmniejszał wartość zmiennej o 1 i wypisywał nową wartość w konsoli. Jak tylko wartość zmiennej osiągnie zero - zatrzymaj timer.

Po naciśnięciu drugiego przycisku zatrzymaj timer. Również zatrzymaj timer, jeśli drugi przycisk nie został naciśnięty, ale wartość zmiennej osiągnęła zero.

Задание 2

Pewien programista napisał kod, który po naciśnięciu przycisku uruchamia timer, wypisujący w konsoli aktualny moment czasu:

html<input type="submit" id="start" value="start">
<input type="submit" id="stop"  value="stop">
javascriptlet start = document.querySelector('#start');
let stop  = document.querySelector('#stop');

start.addEventListener('click', function() {
  let timerId = setInterval(function() {
    let date = new Date;
    console.log(date.getMinutes() + ' ' + date.getSeconds());
  }, 1000);
});

stop.addEventListener('click', function() {
  clearInterval(timerId);
});

Po uruchomieniu kodu, jednakże, okazało się, że przycisk zatrzymania nie działa. Popraw błąd autora kodu.

Задание 3

Kolejny programista także napisał kod dla rozwiązania poprzedniego zadania:

html<input type="submit" id="start" value="start">
<input type="submit" id="stop"  value="stop">
javascriptlet start = document.querySelector('#start');
let stop  = document.querySelector('#stop');

let timerId;

start.addEventListener('click', function() {
  let timerId = setInterval(function() {
    let date = new Date;
    console.log(date.getMinutes() + ' ' + date.getSeconds());
  }, 1000);
});

stop.addEventListener('click', function() {
  clearInterval(timerId);
});

Po uruchomieniu kodu, jednakże, znów okazało się, że przycisk zatrzymania nie działa. Popraw błąd autora kodu.

Задание 4

Kolejny programista także napisał kod dla rozwiązania poprzedniego zadania:

html<input type="submit" id="start" value="start">
<input type="submit" id="stop"  value="stop">
javascriptlet start = document.querySelector('start');
let stop  = document.querySelector('stop');

let timerId;

start.addEventListener('click', function() {
  setInterval(function() {
    let date = new Date;
    console.log(date.getMinutes() + ' ' + date.getSeconds());
  }, 1000);
});

stop.addEventListener('click', function() {
  clearInterval(timerId);
});

Po uruchomieniu kodu, jednakże, znów okazało się, że przycisk zatrzymania nie działa. Popraw błąd autora kodu.

Задание 5

Kolejny programista także napisał kod dla rozwiązania poprzedniego zadania:

html<input type="submit" id="start" value="start">
<input type="submit" id="stop"  value="stop">
javascriptlet start = document.querySelector('start');
let stop  = document.querySelector('stop');

let timerId;

start.addEventListener('click', function() {
  let timerId = setInterval(function() {
    let date = new Date;
    console.log(date.getMinutes() + ' ' + date.getSeconds());
  }, 1000);
});

stop.addEventListener('click', function() {
  clearInterval();
});

Po uruchomieniu kodu, jednakże, znów okazało się, że przycisk zatrzymania nie działa. Popraw błąd autora kodu.

Задание 6

Przytoczony przeze mnie w części teoretycznej kod nie uwzględnia tego, że na przycisk start można wykonać kilka naciśnięć. Dla poprawienia tego problemu można po naciśnięciu przycisku start odwiązać zdarzenie od tego przycisku, a po naciśnięciu przycisku stop - powiązać z powrotem. Popraw problem.