PR

JavaScriptでタイマーの作り方【setIntervalの使い方】

ソースコード

全体のソースコード

まずは完成したソースコードをご覧ください。

HTMLのコード

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css" />
  <title>タイマー</title>
</head>

<body>
  <div id="container">
    <h1>⏳タイマー⌛️</h1>
    <div id="time">0.00</div>
  </div>
  <script src="script.js"></script>
</body>

</html>

CSSのコード

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

h1 {
  font-size: 64px;
  text-align: center;
}

#container {
  width: 640px;
  margin: 0 auto;
  padding: 32px;
}

#time {
  font-size: 100px;
  text-align: center;
  padding: 32px;
  border-radius: 48px;
  box-shadow: 0 0 20px rgb(0 0 0 / .5);
}

JavaScriptのコード

// ============ 変数 ============

// 要素の設定
const body = document.getElementsByTagName("body")
const time = document.getElementById("time")

// 開始時間
let startTime = Date.now()

// 停止時間
let stopTime = 0

// 時間を止めるフラグ
let flg = 1


// ============ 関数 ============

// 時間を表示する関数
function displayTime() {
  if (flg == 0) {
    let currentTime = Date.now() - startTime + stopTime

    currentTime = currentTime / 1000

    time.textContent = currentTime.toFixed(2)
  }
}


// ========= スマホ操作 ==========

// タップしたら時間を動かす・止める
body[0].addEventListener("touchstart", () => {
  if (flg == 0) {
    flg = 1
    stopTime += (Date.now() - startTime)
  } else {
    flg = 0
    startTime = Date.now()
  }
})

// ダブルタップしたら時間をリセットする
body[0].addEventListener("dblclick", () => {
  flg = 1
  stopTime = 0
  time.textContent = "0.00"
})


// ============ 実行 ============

// 一定時間ごとに関数を実行する
setInterval(displayTime, 10)

「JSAnywhere」を使って動かしてみる

お持ちのスマホやタブレットにJSAnywhereをインストールすることで、簡単にJavaScriptでのプログラミングができるようになります。

JSAnywhereを使って、タイマーWebアプリを動かしてみたいと思います。

1.新しいプロジェクトを作る

JSAnywhereを開いたら右上の「+」を押して、プロジェクト名を決めます。

プロジェクト名を入力して、右上の「保存」を押します。

2.ソースコードをコピーして貼り付ける

作ったプロジェクトの「HTML」を開いて、すべて削除します。

「すべてを選択」して「×」を押すと早く消せます。

このページにあるHTMLコードの「Copy」を押してコピーします。

JSAnywhereの「HTML」に「ペースト」して貼り付けます。

同様に「CSS」と「JavaScript」もすべて消してからコピーして貼り付けます。

3.実行して動作チェックする

右上にある「▶︎」ボタンを押してみましょう。

プレビューが表示されました。これが実際に表示されるブラウザ画面になります。

画面のどこでもいいのでタップするとタイマーが動きはじめます。

もう一度タップすると、タイマーが止まります。

これでタイマーWebアプリが完成しました。

HTMLの解説

HTMLとは、ホームページなどのウェブサイトを制作するためのマークアップ言語です。

マークアップ言語は、目印(タグ)で囲むことで文書の内容に意味を持たせる書き方です。

<head>、<body>、<h1>、<div> などがタブと呼ばれるものになります。

今回は、

・大きな見出しで「タイマー」と表示
・経過時間を1/100秒で表示(0.00)

をHTMLで作ります。

HTMLの基本

<!DOCTYPE html>
<html>

<head>
  :
</head>

<body>
  :
</body>

</html>
<!DOCTYPE html>

HTMLのバージョンが「HTML5」モードであることを宣言しています。

省略すると、HTMLのバージョンは過去互換モードになります。

<html> .. </html>

<html> .. </html> で囲んだ部分が、HTML文書であることを指定します。

<head> .. </head>

<head> </head> で囲んだ部分がヘッダ部になります。

ヘッダには、文書全体に関する指定などを書きます。

<html> が親要素になり、<html> .. </html> の中に入ります。

<body> .. </body>

<body> </body> で囲んだ部分がボディ部になります。

ボディは、文書の本文を記述するところになります。ホームページを見たときに表示される内容です。

<html> が親要素になり、<html> .. </html> の中に入ります。

<head>内の解説

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css" />
  <title>タイマー</title>
</head>
<meta charset=”utf-8″>

文字コードを指定します。文字化け防止に必要です。

<link rel=”stylesheet” href=”style.css”>

外部スタイルシートを指定します。

“style.css” が、外部CSSのファイル名になります。

<title>タイマー</title>

タイトルを指定します。タイトルを「タイマー」にしています。

タイトルは、ブラウザのツールバーや検索エンジンの検索結果などで表示されます。

<body>内の解説

<body>
  <div id="container">
    <h1>⏳タイマー⌛️</h1>
    <div id="time">0.00</div>
  </div>
  <script src="script.js"></script>
</body>
<div id=”container”> .. </div>

<div> </div> で囲んだ部分は、前後に改行が挿入されて表示されるブロック要素です。

「id」や「class」を指定することで、CSSやJavaScriptで利用できる要素になります。

今回は、id=”container” でid名を指定して、CSSで見栄えやスタイルを定義するのに利用します。

id属性は同じ名前のidを一つのHTML内に一つだけしか指定できませんが、class属性は同じ名前のclassを一つのHTML内に複数指定することができます。

<h1>⏳タイマー⌛️</h1>

<h1> </h1> で囲んだ部分は、大きな見出しで表示されるブロック要素です。

表示される文字は「⏳タイマー⌛️」です

<div id=”time”>0.00</div>

<div> </div> で囲んだ部分は、前後に改行が挿入されて表示されるブロック要素です。

表示される文字は「0.00」です。

今回は、id=”time” でid名を指定して、CSSで見栄えやスタイルを定義するのに利用します。

見栄えやスタイルを定義していない状態では、このように表示されます。

⏳タイマー⌛️

0.00
<script src=”script.js”></script>

外部JavaScriptを指定します。

“script.js” が、外部JavaScriptのファイル名になります。

CSSの解説

CSSとは、ホームページなどのウェブサイトのレイアウトやデザインといった見た目を指定するスタイルシートです。

CSSを適用させる要素のことを「セレクタ」と呼び、セレクタの「プロパティ」に「プロパティの値」を指定します。

セレクタ {
    プロパティ: 値;
}

html { .. } 内の解説

html {
  height: 100%;
}

<html> </html> で囲まれた部分のスタイルを指定します。

height: 100%;

表示する高さを、画面の高さ100%に指定します。

body { .. } 内の解説

body {
  height: 100%;
  margin: 0;
}

<body> </body> で囲まれた部分のスタイルを指定します。

height: 100%;

表示する高さを、<html>の高さ100%に指定します。

<body>だけ高さ100%にしても親要素<html>の高さまでにしかなりません。
画面いっぱいの高さにするためには、<html>の要素の高さも100%にする必要があります。

margin: 0;

周りの要素との間の隙間を、0に指定します。

ほとんどの要素でmarginの初期値は0ですが、body要素の初期値は8pxなので周りの要素との間の隙間をなくすためにmarginの値を0に指定しています。

h1 { .. } 内の解説

h1 {
  font-size: 64px;
  text-align: center;
}

<h1> </h1> で囲まれた部分のスタイルを指定します。

font-size: 64px;

文字の大きさを、64pxに指定します。

text-align: center;

テキストの配置を、中央寄せに指定します。

#container { .. } 内の解説

#container {
  width: 640px;
  margin: 0 auto;
  padding: 32px;
}

idが「container」の要素のスタイルを指定します。

要素名の頭に「#」が付くとidを、要素名の頭に「.」が付くとclassを指定します。

width: 640px;

要素の幅を、640pxに指定します。

margin: 0 auto;

周りの要素との間の隙間を、上下を0に指定し、左右を自動(中央寄せ)に指定します。

padding: 32px;

要素の内側の余白を、32pxに指定します。

#time { .. } 内の解説

#time {
  font-size: 100px;
  text-align: center;
  padding: 32px;
  border-radius: 48px;
  box-shadow: 0 0 20px rgb(0 0 0 / .5);
}

idが「time」の要素のスタイルを指定します。

要素名の頭に「#」が付くとidを、要素名の頭に「.」が付くとclassを指定します。

font-size: 100px;

文字の大きさを、100pxに指定します。

text-align: center;

テキストの配置を、中央寄せに指定します。

padding: 32px;

要素の内側の余白を、32pxに指定します。

border-radius: 48px;

要素の周囲に、角の丸いボーダーラインを描画します。

丸い角の半径を48pxに指定します。

box-shadow: 0 0 20px rgb(0 0 0 / 0.5);

要素の周囲(ボーダーライン)に影をつけます。

左右のズレを 0、上下のズレを 0、ぼかしの長さを 20pxで、黒い半透明の影をつけます。

rgb(0 0 0 / .5) は、rgb(0 0 0)で黒を表し「/ .5」(アルファチャネル値)を付けることで半透明になります。
「/ 0」または「/ 0%」で完全に透明、「/ 1」または「/ 100%」で完全に不透明になります。

スタイルを定義して、このように表示されるようになりました。

⏳タイマー⌛️

0.00

JavaScriptの解説

JavaScriptとは、ホームページなどのウェブサイトに動きを加えたり複雑な機能を定義するプログラミング言語です。

今回は、

・画面をタップしたら時間を動かす
・経過時間を表示
・もう一度タップしたら時間を止める

という動きをJavaScriptで作ります。

変数を宣言する

変数とは、数値や文字列などの値を名前をつけて保存するものです。

変数には大きく分けて

・コードの重複を減らして見やすくする
・処理によって変わる数値や文字列

を目的に使われることが多いです。

予期しないエラーを出さないためにも同じ名前の変数を作ること(再宣言)ができない「const」や「let」で変数を宣言するのがいいです。

値が変わらない変数(定数)には、再代入ができない「const」で変数を宣言するのに最適です。
値が変わる変数には、再代入(値を変えることが)できる「let」を使います。

再宣言(同じ名前の変数を作ること)も再代入(値を変えること)も可能になる「var」で変数を宣言することは、現在はあまり推奨されていません。

// ============ 変数 ============

// 要素の設定
const body = document.getElementsByTagName("body")
const time = document.getElementById("time")

// 開始時間
let startTime = Date.now()

// 停止時間
let stopTime = 0

// 時間を止めるフラグ
let flg = 1
const body = document.getElementsByTagName(“body”)

<body>タグの要素情報を、bodyという名前の変数に代入します。

document.getElementsByTagName( .. ) で、HTML内にある指定したタグ名の要素を参照します。

タグ名が一致する要素をすべて取得します。

<body>のように1つしかないタグの場合も、呼び出すときは body[0] のように呼び出します。

const time = document.getElementById(“time”)

id名が”time”の要素情報を、timeという名前の変数に代入します。

document.getElementById( .. ) で、HTML内にある指定したid名の要素を参照します。

let startTime = Date.now()

開始時間を、startTimeという名前の変数に代入します。

Date.now() は、1970年1月1日 0時0分0秒から現在までの秒数(ミリ秒単位)を取得することができます。

let stopTime = 0

停止時間を、stopTimeという名前の変数に代入します。停止時間の初期値は 0です。

let flg = 1

時間を止めるフラグを、flgという名前の変数に代入します。

flg が 1 のときはタイマーの時間が止まり、flg が 0 のときにタイマーの時間が動きます。

関数を作成する

function 関数名() { .. } で関数を定義することで、同じ処理を何度も呼び出して実行できるようになります。

ここでは、経過時間を表示する関数を作成します。

// ============ 関数 ============

// 時間を表示する関数
function displayTime() {
  if (flg == 0) {
    let currentTime = Date.now() - startTime + stopTime
    currentTime = currentTime / 1000
    time.textContent = currentTime.toFixed(2)
  }
}

時間を止めるフラグ flg が 0 のときに、タイマーの表示時間を新しい時間に書き換えます。

function displayTime() { .. }

関数名を、displayTimeという名前で定義します。呼び出すことで  { } 内の処理が実行されます。

if (flg == 0) { .. }

「if文」です。時間を止めるフラグ flg が 0 なら、{ } 内の処理を行います。

if文は、条件を満たすときに { } 内の処理を行います。条件を満たさないときは { } 内の処理を飛ばします。

if (条件) {
    処理
}

のように記述します。

let currentTime = Date.now() – startTime + stopTime

現在の時間 Date.now() から開始時間 startTime を引くことで、経過時間 currentTime になります。

一度時間を止めたてから再度時間を進めるときは、止めたときの経過時間を引き継ぐ必要があります。

再開した経過時間 (Date.now() – startTime) に、停止時間 stopTime を足すことで経過時間 currentTime になります。

currentTime = currentTime / 1000

今の経過時間 currentTime はミリ秒単位ですので、1000 で割ることで秒単位に直します。

1秒が「1000」ミリ秒なので、1000で割って「1.000」秒にします。

time.textContent = currentTime.toFixed(2)

経過時間を表示する要素 time に、経過時間 currentTime を表示します。

time.textContent は、要素timeに表示される文字列です。

currentTime.toFixed(2) は、変数currentTimeの値(数値)を固定小数点表記の文字列に変換します。

例:toFixed(2) で、小数点の第2位までを残した文字列に変換
1 → ‘1.00’
12.345 → ‘12.35’
0.004 → ‘0.00’
小数点第3位で四捨五入されます。

スマホ操作(イベント処理を実行する)

タップされたら時間を動かして、もう一度タップされたら時間を止める処理を行います。

// ========= スマホ操作 ==========

// タップしたら時間を動かす・止める
body[0].addEventListener("touchstart", () => {
  if (flg == 0) {
    flg = 1
    stopTime += (Date.now() - startTime)
  } else {
    flg = 0
    startTime = Date.now()
  }
})

// ダブルタップしたら時間をリセットする
body[0].addEventListener("dblclick", () => {
  flg = 1
  stopTime = 0
  time.textContent = "0.00"
})

時間を止めるフラグ flg を 1 から 0 にしたら、時間が動きます。

body[0].addEventListener(“touchstart”, () => { .. })

body要素上でタップしたときに、{ } 内の関数を実行します。


対象の要素.addEventListener(特定の操作, 関数)

タッチイベント“touchstart” :タップしたとき(画面に指が触れたとき)に、関数を実行します。

アロー関数 () => { .. }

アロー関数は、function の代わりに => を記述する関数です。

従来の関数のように「関数を定義して、関数を呼び出す」のではなく、アロー関数はそのまま実行されます。

従来の関数

function 関数名() {
  処理
}

関数名()

アロー関数

() => {
  処理
}
if (flg == 0) { .. } else { .. }

「if..else文」です。時間を止めるフラグ flg が 0 なら前の { } 内の処理を行い、flg が 0 でなければ後ろの { } 内の処理を行います。

flg = 1|stopTime += (Date.now() – startTime)

時間を止めるフラグ flg を 1 にします。(時間を止めます。)

停止時間 stopTime に、経過時間 (Date.now() – startTime) を足します。

例えば 5秒後に時間を止めたら、元の停止時間(初期値 0)に経過時間(5秒)を足して、停止時間 stopTime は 5秒になります。

flg = 0|startTime = Date.now()

時間を止めるフラグ flg を 0 にします。(時間を動かします。)

開始時間 startTime を、現在の時間 Date.now() にします。

body[0].addEventListener(“dblclick”, () => { .. })

body要素上でダブルクリック(ダブルタップ)したときに、{ } 内の関数を実行します。

flg = 1|stopTime = 0

時間を止めるフラグ flg を 1 にします。(時間を止めます。)

停止時間 stopTime を、0 にします。

time.textContent = “0.00”

経過時間を表示する要素 time に、0.00 を表示します。

実行する(関数を呼び出す)

経過時間を表示する関数 displayTime を呼び出して実行します。

一定時間毎に関数を実行する setInterval を利用します。

// ============ 実行 ============

// 一定時間ごとに関数を実行する
setInterval(displayTime, 10)

setInterval(displayTime, 10)

経過時間を表示する関数 displayTime を 0.01秒毎に呼び出して実行します。

setInterval(繰り返し実行したい関数名, 経過するたびに関数を呼び出す時間)

経過するたびに関数を呼び出す時間はミリ秒単位で「 1000 」が 1秒です。

例:「 10 」なら 0.01秒ごとに繰り返し処理します。

改行とインデントとコメントアウトの意味

インデントとは、より読みやすくするために行の最初の部分に空白を挿入することです。字下げとも呼ばれます。

改行してインデントした場合


body[0].addEventListener("touchstart", () => {
  if (flg == 0) {
    flg = 1
    stopTime += (Date.now() - startTime)
  } else {
    flg = 0
    startTime = Date.now()
  }
})

ソースコードは改行しなければ読みにくいです。


body[0].addEventListener("touchstart", () => {if (flg == 0) {flg = 1; stopTime += (Date.now() - startTime)} else {flg = 0; startTime = Date.now()}})

改行してもインデントしなければ、


body[0].addEventListener("touchstart", () => {
if (flg == 0) {
flg = 1
stopTime += (Date.now() - startTime)
} else {
flg = 0
startTime = Date.now()
}
})

のようになり、入れ子構造がわかりにくいです。

どれでも同じように実行されますが、インデント(行の最初の部分に空白を挿入)することで読みやすいソースコードになります。

コメントアウトとは、プログラムに影響しないようにソースコード上に文字や文章を入れられる機能のことです。

コメントアウト機能を使ってソースコードやプログラムの一部分を無効化できます。

・あとで読むときに理解しやすくするため
・コード全体の構成をわかりやすくするため
・あとで復活させるかもしれない内容を消さずに取っておくため

のような目的で使われることが多いです。

HTML のコメントアウト



<!-- この中がコメントになります -->

<!--
  この行が
  コメントに
  なります
-->

CSS のコメントアウト



/* この中がコメントになります */

/*
  この行が
  コメントに
  なります
*/

JavaScript のコメントアウト



// この中がコメントになります

/*
  この行が
  コメントに
  なります
*/