BMI計算機を作ろう
前章「HTMLとの連携」で、ユーザーの操作を検知してWebページを動的に書き換える方法を学びました。その応用編として、もう少しだけ実用的な「BMI計算機」を作って行きたいと思います。
BMIとは、身長と体重から「肥満度」を算出するものです。
BMI = 体重 kg ÷ (身長 m × 身長 m)
例えば 身長 170cm、体重 72kg ならば
72 / (1.7 * 1.7) = 23.7812128
BMI計算アプリでは小数点第二位以下を切り捨てて、 23.7 という結果をユーザーに提示する仕様にしたいと思います。
事前準備
今までは js-basicフォルダのなかの index.html と main.js を使ってきましたが、今回はプロジェクトフォルダを分けることにしましょう。
同じく js-basicフォルダの中に「bmi」という名前のフォルダを作って下さい。そしてその中に「index.html」と「main.js」ファイルを作成してください。この2つのファイルでBMI計算機を作っていきます。
js-basic
└ index.html
└ main.js
└ bmi
└ index.html
└ main.js
HTMLファイル
HTMLはあらかじめこちらで用意したものをコピーして bmi/index.html ファイルに貼り付けてください。
見た目がキレイになるように Bootstrap というCSSフレームワークを使っています。最低限のデザインが簡単に適用できるものです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BMI計算機</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head>
<body>
<header>
<nav class="navbar navbar-dark bg-dark">
<div class="container">
<a href="#" class="navbar-brand">BMI計算機</a>
</div>
</nav>
</header>
<main>
<div class="container">
<div class="row">
<section class="col-sm-6 col-md-4 pt-4">
<div class="form-group">
<label for="height">身長 (cm)</label>
<input id="height-input" type="text" class="form-control" value="">
</div>
<div class="form-group">
<label for="weight">体重 (kg)</label>
<input id="weight-input" type="text" class="form-control" value="">
</div>
<input id="button-submit" type="submit" class="btn btn-primary btn-large" value="計測開始">
</section>
<section class="col-sm-6 col-md-4 pt-4">
<div class="card">
<div class="card-header">
あなたのBMIは
</div>
<div class="card-body">
<div id="bmi-output" class="display-4"></div>
</div>
</div>
</section>
</div>
</div>
</main>
<script src="main.js"></script>
</body>
</html>
bmi/index.htmlファイルをChromeで開いて、正常に表示されているかを確認してください。
ロジックを考えよう
見た目の方はとりあえず完成してしまいました。しかしながら肝心の「BMIを計算する」というロジックは、まだ何ひとつできていません。それを main.js に書いていくことにしましょう。 その前に要件を整理しておきます。
ユーザー側のアクションとリアクションは次の通りです。
- 身長をセンチメートル単位で入力する
- 体重をキログラム単位で入力する
- 計測開始ボタンを押す
- BMIが表示される
3 と 4 の間の部分の処理を開発者側で仕込んでおく必要がありますね。計測開始ボタンが押された時に行いたい処理内容は次の通りです。
- 入力された身長の値を取得する
- 入力された体重の値を取得する
- 身長をメートルに換算する
- 身長と体重から BMI を計算する
- BMI の小数点第二位以下を切り捨てる
- BMI を指定箇所に表示する
このような内容となるでしょう。
また「計測開始ボタンが押された」ことを検知する必要がありますし、身長・体重の各入力値を受け取るには、その要素をJavascriptで特定しなければなりません。
前章やったで「見出しがクリックされた時」を思い出してみてください。
var h1 = document.getElementsByTagName('h1');
h1[0] = ...
こんな風にdocumentオブジェクトを操作して目的の要素を取得していました。
getElementsByTagNameは復数の要素を配列として取得するので、やや扱いにくいです。今回は id を使ってピンポイントで目的の要素を取得する方法をご紹介します。
getElementById
あらかじめ bmi/index.html には特定のタグに id を割り当てておきました。
<label for="height">身長 (cm)</label>
<input id="height-input" type="text" class="form-control" value="">
<!-- -->
<label for="weight">体重 (kg)</label>
<input id="weight-input" type="text" class="form-control" value="">
<!-- -->
<input id="button-submit" type="submit" class="btn btn-primary btn-large" value="計測開始">
<!-- -->
<div id="bmi-output" class="display-4"></div>
必要となる要素の情報とは、ユーザーから受け付ける入力値の要素と、BMIを表示させる要素です。
入力要素
- id="height-input"
- id="weight-input"
- id="button-submit"
出力要素
- id="bmi-output"
この4つになります。HTMLの各要素にはこのように、任意の値の id を割り当てることができます。そしてJavascriptでHTMLを操作する時は、id を使って次のように要素の情報を取得することができます。
document.getElementById('id名')
ロジックを書いてみよう
必要な情報はだいぶ揃ってきました。それではいよいよ、main.js にBMI計算ロジックを書いていきましょう。
// 入力要素を取得
var height = document.getElementById('height-input'); // 身長入力欄
var weight = document.getElementById('weight-input'); // 体重入力欄
var button = document.getElementById('button-submit'); // 計測開始ボタン
// 出力要素を取得
var output = document.getElementById('bmi-output'); // BMI表示場所
// 入力値からBMIを計算して指定場所に表示する関数
var calcBmi = function () {
// ...
}
// 計測開始ボタンが押されたときの処理を登録(イベントリスナー)
button.addEventListener('click', calcBmi);
おおまかな構成としてはこれで良いと思います。あとは、calcBmi関数の中身を書いていくだけです。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
// 2.入力された体重の値 (kg)を取得
// 3.身長(cm)をメートルに換算する
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
// 5.BMIの小数点第一位以下切り捨て
// 6.BMIを表示
}
やりたいことはこの 6 つになります。
1. 身長の入力値を取得する
身長入力欄の要素情報(オブジェクト)はあらかじめ取得してあります。
var height = document.getElementById('height-input');
これは単に入力された値だけでなく、 height-input の id が割り当てられた次のタグに関する様々な情報を持っています。
<input id="height-input" type="text" class="form-control" value="">
ユーザーが入力した身長の値は、現在は空文字になっている value 属性に入ることになります。この値は次のように .value
とすることで取得できます。
var height = document.getElementById('height-input');
height.value;
.value を使って、calcBmi()関数の 1 番目のロジックを完成させましょう。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
// 5.BMIの小数点第一位以下切り捨て
// 6.BMIを表示
}
2. 体重入力値を取得する
身長と同様です。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
// 5.BMIの小数点第一位以下切り捨て
// 6.BMIを表示
}
身長(cm)をメートルに換算する
センチメートルをメートルに換算するには、100 で割れば良いですね。
h_value = h_value / 100;
または次のように書くこともできます。
h_value /= 100;
したがって、calcBmi()関数の 3 番目のロジックはこうなります。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
h_value /= 100;
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
// 5.BMIの小数点第一位以下切り捨て
// 6.BMIを表示
}
4.BMIを計算する
BMIの計算方法は
BMI = 体重 kg ÷ (身長 m × 身長 m)
でした。現在すでにメートルに換算した身長と、体重(kg)の値は変数に保持してあるので、これを使えば良いですね。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
h_value /= 100;
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
var bmi = w_value / (h_value * h_value);
// 5.BMIの小数点第一位以下切り捨て
// 6.BMIを表示
}
5.BMIの小数点第一位以下切り捨て
ただしこのままだと、きれいに割り切れない場合は小数点以下がずっと続いてしまいます。小数点第二位以下を切り捨ててみましょう。
小数点の切り捨てを行うには、Mathオブジェクトのfloor()メソッドというものを使用します。
例えば 123.4567 という浮動小数値があった場合、次のようにすると整数部分 123
だけを取得できます。
Math.floor(123.4567)
もし小数点第一位までを残して、第二位以下を切り捨てたい場合は、ちょっとしたテクニックが必要です。
Math.floor(123.4567 * 10) / 10;
123.4567 を一旦 10 倍にしてから floor() で切り捨て、その後に 10 で割ることで桁を戻しています。BMIもこの方法を使いましょう。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
h_value /= 100;
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
var bmi = w_value / (h_value * h_value);
// 5.BMIの小数点第一位以下切り捨て
bmi = Math.floor(bmi * 10) / 10;
// 6.BMIを表示
}
6.BMIを表示
これでようやくBMIが計算できました。あとはこれを指定の場所に表示するだけです。指定場所の要素はあらかじめ取得しておきました。
var output = document.getElementById('bmi-output'); // BMI表示場所
これはHTMLの次の要素を取得しています。
<div id="bmi-output" class="display-4"></div>
<div>
と </div>
の間にBMIを表示したいので、innerHTMLプロパティを使います。
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
h_value /= 100;
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
var bmi = w_value / (h_value * h_value);
// 5.BMIの小数点第一位以下切り捨て
bmi = Math.floor(bmi * 10) / 10;
// 6.BMIを表示
output.innerHTML = bmi;
}
これでようやくロジック部分も完成しました。
完成形
// 入力要素を取得
var height = document.getElementById('height-input'); // 身長入力欄
var weight = document.getElementById('weight-input'); // 体重入力欄
var button = document.getElementById('button-submit'); // 計測開始ボタン
// 出力要素を取得
var output = document.getElementById('bmi-output'); // BMI表示場所
// 入力値からBMIを計算して指定場所に表示する関数
var calcBmi = function () {
// 1.入力された身長の値 (cm)を取得
var h_value = height.value;
// 2.入力された体重の値 (kg)を取得
var w_value = weight.value;
// 3.身長(cm)をメートルに換算する
h_value /= 100;
// 4.BMIを計算する:体重 ÷ (身長 m × 身長 m)
var bmi = w_value / (h_value * h_value);
// 5.BMIの小数点第一位以下切り捨て
bmi = Math.floor(bmi * 10) / 10;
// 6.BMIを表示
output.innerHTML = bmi;
}
// 計測開始ボタンが押されたときの処理を登録(イベントリスナー)
button.addEventListener('click', calcBmi);
bmi/index.html をブラウザで開いて、動作確認をしてみて下さい。あなたの身長と体重を入力したら、BMIが正しく表示されたでしょうか?
まとめ
いかがでしたか?
無料体験入門はこれで終わりです。Javascriptを使ってのプログラミングによって、最終的にはユーザーの身長と体重からBMIを表示させるWebアプリケーションを完成させることができました。
このように、ブラウザだけでWebページを動的に操ることを得意とするのが、Javascriptの大きな特徴です。
もちろん、体験入門ではまだまだ学習が足りない部分がたくさんあります。特に、条件分岐(if文)やループ処理(for文)についてはほとんど触れてきませんでしたが、これらはプログラミングのごく初歩的な内容です。また、関数やオブジェクトについてももっと深い学習が必要となってきます。
しかしながら、この体験入門を通じて少なくとも「命令をあらかじめ定義しておき、コンピュータに処理を実行させる」という経験を積むことは出来たと思います。
エンジニアという新しい門をくぐって、その第一歩は踏み出せたのではないでしょうか。
ニューモンズではJavascript以外にもさまざまな言語の学習コースを用意しています。興味のあるコースをぜひ継続的に受講してみて下さい。
あなたの正式な「入門」をお待ちしております!