JavaScriptでのタイマー起動・停止ボタン

それでは、2つのボタンを作成しましょう:1つ目のボタンをクリックするとタイマーが起動し、2つ目のボタンをクリックすると停止するようにします。ここではすでにすべてが単純ではなく、落とし穴が待ち構えています。この落とし穴の本質を理解するために、コード作成の手順を段階的に説明します。

では、2つの小さなボタンを作成します:

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

これらのボタンへの参照を変数に取得します:

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

1つ目のボタンをクリックして、その番号を変数に記録してタイマーを起動します:

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

では、2つ目のボタンをクリックしてタイマーを停止させましょう:

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

// タイマーを停止します:
stop.addEventListener('click', function() {
  clearInterval(timerId);
});

しかし、上記のコードを実行しようとすると、驚きが待っています:タイマーを停止しようとすると、変数 timerId が undefined であることが判明します!なぜこうなったのでしょうか?タイマーを起動するとき、変数 timerId を start ボタンにバインドされた関数内でローカルにしてしまったからです。

この問題を解決するために、変数 timerId をグローバルにします。これにより、タイマー起動関数内でも停止関数内でもアクセス可能になります:

javascriptlet timerId; // 変数をグローバルにします

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

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

初期値として数値 100 が格納されている変数があるとします。また、2つのボタンがあります。1つ目のボタンをクリックすると、タイマーが起動し、毎秒変数の値を 1 ずつ減少させ、新しい値をコンソールに出力します。変数の値がゼロに達したら、タイマーを停止してください。

2つ目のボタンをクリックすると、タイマーを停止してください。また、2つ目のボタンがクリックされていなくても、変数の値がゼロに達した場合もタイマーを停止してください。

Задание 2

あるプログラマーが、ボタンをクリックすると現在時刻をコンソールに出力するタイマーを起動するコードを書きました:

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);
});

しかし、コードを実行した後、停止ボタンが機能しないことが判明しました。コードの著者の誤りを修正してください。

Задание 3

別のプログラマーも前のタスクを解決するためにコードを書きました:

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);
});

しかし、コードを実行した後、またしても停止ボタンが機能しないことが判明しました。コードの著者の誤りを修正してください。

Задание 4

別のプログラマーも前のタスクを解決するためにコードを書きました:

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);
});

しかし、コードを実行した後、またしても停止ボタンが機能しないことが判明しました。コードの著者の誤りを修正してください。

Задание 5

別のプログラマーも前のタスクを解決するためにコードを書きました:

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();
});

しかし、コードを実行した後、またしても停止ボタンが機能しないことが判明しました。コードの著者の誤りを修正してください。

Задание 6

理論的な部分で私が示したコードは、スタートボタンが複数回クリックされる可能性を考慮していません。この問題を修正するには、スタートボタンをクリックしたときにそのボタンからイベントを解除し、ストップボタンをクリックしたときに再度バインドすることができます。この問題を修正してください。