コース一覧
JavaScriptでWebページを動かす
setTimeout と setInterval

JavaScriptでWebページを動かす

DOM から要素を取得・更新・追加し、クリック・入力・フォーム送信に反応する処理を作る全 20 レッスン(411 分)のコースです。タイマーと localStorage も使い、最後は入力を保存できるひとことメモを仕上げます。用意された HTML/CSS を使うため、学習の中心は JavaScript です。

1
DOM のきほん
01. DOM とは何か15分
02. 要素を取得する20分
03. テキストを書き換える20分
04. class を付け外しする20分
05. 要素を作って追加する20分
06. 配列から一覧を描画する25分
07. つくる ギャラリーをデータ駆動にする30分
08. 第1章まとめクイズ10分
2
イベント処理
01. クリックに反応する18分
02. event オブジェクト20分
03. 入力欄の値を取る18分
04. フォーム送信を制御する20分
05. つくる ダークモード切替25分
06. つくる フォームの入力チェック25分
07. 第2章まとめクイズ10分
3
タイマーと総合制作
01. setTimeout と setInterval20分
02. localStorage で保存する20分
03. つくる ひとことメモウィジェット30分
04. 自由拡張30分
05. 完成と次のステップ15分

setTimeout と setInterval

同期と非同期
解説

このレッスンで分かること

  • setTimeout(関数, ミリ秒) は「あとで 1 回だけ呼んでね」という予約です
  • setInterval(関数, ミリ秒) は clearInterval で止めるまで呼び続けます

3 秒待たせると、その 3 秒だけページが死ぬ

ここまで書いてきたコードは、上から下へ 1 行ずつ動いてきました。JavaScript には作業員が 1 人しかいない、と考えると分かりやすいです。この作業員は、手に持っている仕事をやり切るまで、ほかの仕事を始められません。

だから「3 秒たったらお知らせを消す」を素直にやろうとして、作業員をその場で 3 秒立ち止まらせると、その 3 秒のあいだページは完全に固まります。ボタンを押しても反応せず、文字も選べません。

そこで使うのが予約という考え方です。「3 秒たったら、この紙に書いた仕事をやってね」と伝えて、自分はすぐ次の行へ進みます。3 秒後、手が空いたときに作業員が紙を拾います。

JavaScript

setTimeout(function () { console.log("3 秒たちました"); }, 3000);

第 1 引数に「あとでやってほしい処理」を関数のまま渡し、第 2 引数に待つ長さをミリ秒で書きます。1 秒なら 1000、0.5 秒なら 500 です。ここを 3 と書くと 3 ミリ秒後、つまりほぼ一瞬で動いてしまうので気を付けてください。

書いた順と、動く順が違う

setTimeout を書いた行で処理が止まるわけではない、というのが最初のつまずきどころです。

JavaScript

console.log("1 番目"); setTimeout(function () { console.log("2 番目のつもり"); }, 1000); console.log("3 番目のつもり");

コンソールに出る順は 1 番目 3 番目のつもり 2 番目のつもり です。予約した処理は、いま動いている流れが終わってから呼ばれるので、下に書いたほうが先に出ます。「1000 ミリ秒後ぴったり」ではなく「1000 ミリ秒たった以降で、手が空いたとき」と覚えておくと、時刻がわずかにずれても慌てずにすみます。

setInterval は書き方がそっくりですが、1 回で終わらず、指定した間隔でずっと呼び続けます。時計のように決まった間隔で表示を新しくしたいときに使います。仕掛けたい処理は先に関数として用意しておき、名前だけを渡します。

関数何をするか止め方
setTimeout指定した時間のあと 1 回だけ呼ぶclearTimeout(番号)
setInterval指定した間隔でくり返し呼ぶclearInterval(番号)

止めないと、ページを離れても動き続ける

setInterval の戻り値は、その予約に付けられた番号です。この番号を変数に取っておかないと、あとで止める手段がありません。

JavaScript

let count = 0; const timerId = setInterval(function () { count = count + 1; console.log(count + " 回目"); if (count === 5) { clearInterval(timerId); } }, 1000);

止め忘れは現場で本当によく起きます。1 秒ごとに動く処理が 10 個たまれば、ページは 1 秒ごとに 10 回の仕事を抱えることになり、スクロールも入力ももたつきはじめます。要素を消したのに、その要素を書き換えようとする予約だけが残って、毎秒エラーを吐き続けることもあります。役目が終わったら必ず止める、と決めておいてください。使い終わった予約が残り続けて動きが鈍っていく状態を、メモリリークと呼びます。

setTimeout のほうも clearTimeout で取り消せます。対象はまだ動いていない予約だけで、すでに実行された予約を取り消すことはできません。

なお、setInterval を仕掛けても、最初の 1 回は指定した時間がたつまで動きません。読み込んだ直後から表示を出したいなら、仕掛ける前に同じ関数を自分で 1 回呼んでおきます。細かい話に見えますが、この一瞬のちらつきの有無が、できあがりの印象を大きく変えます。

よくある間違い

  • かっこを付けて呼んでしまう — setInterval(reload(), 1000) は reload() をその場で実行し、その戻り値を予約しています。渡すのは関数そのものなので、かっこは付けません
  • 戻り値を受け取らない — 番号を変数に入れておかないと clearInterval に渡すものがなく、二度と止められません
  • 秒とミリ秒を取り違える — setTimeout(fn, 3) は 3 秒後ではなく 3 ミリ秒後です。3 秒待たせたいなら 3000 と書きます

課題

  1. ヘッダーに、時刻を出す id が clock の p と、止める id が clock-stop の button と、状態を出す id が clock-status の p と、お知らせ用の id が notice の p を足す
  2. showTime 関数を作り、clock に時刻を入れる。読み込んだ直後に 1 回呼んでおく
  3. setInterval で 1 秒ごとに showTime を呼び、戻り値の番号を変数に入れておく
  4. clock-stop を押したら clearInterval で止め、clock-status に停止中と分かる文を入れる
  5. setTimeout を 1 つ使い、notice に出したお知らせを 5 秒後に消す

ヒント

予約するのは関数そのものです。かっこを付けずに `setInterval(showTime, 1000)` と渡します

時刻は `new Date()` から `getHours` `getMinutes` `getSeconds` で取り出します。`String(値).padStart(2, "0")` で 2 桁にそろえると読みやすくなります

止めるには setInterval の戻り値が要ります。`const clockTimer = setInterval(...)` のように番号を変数へ入れてから clearInterval に渡してください

index.html
style.css
script.js
プレビュー

できているか

  • 時刻を出す #clock がある
  • 止めるボタン #clock-stop がある
  • お知らせを出す #notice がある
  • 読み込んだ直後から #clock に時刻が出ている
  • #clock-stop を押すと #clock-status に停止中と出る
エディタを読み込んでいます