[JavaScript] 計算コンテンツ用の雛形テンプレート
ウェブサイト上に簡易な計算コンテンツを設置する際のテンプレートを検討してみました。
サンプルコード
html
<div class="calculator">
<dl class="calculator_input">
<dt>上底</dt>
<dd><input type="text" id="joutei"></dd>
<dt>下底</dt>
<dd><input type="text" id="katei"></dd>
<dt>高さ</dt>
<dd><input type="text" id="takasa"></dd>
</dl>
<div class="calculator_action">
<button class="calculator_action_reset">リセット</button>
<button class="calculator_action_calc">計算</button>
</div>
<dl class="calculator_result">
<dt>計算結果</dt>
<dd></dd>
</dl>
</div>
入力項目や計算の実行ボタン、入力内容のリセットボタンを配置するhtmlです。
各入力項目のinputタグには「takasa」などの固有のidを設定しています。後述するJavaScriptの処理で、このidを使用して入力項目の値を参照します。
CSS
.calculator {
margin: 0px auto;
max-width: 600px;
}
.calculator * {
box-sizing: border-box;
}
.calculator_input {
display: flex;
align-items: center;
flex-wrap: wrap;
margin: 0px;
}
.calculator_input dt,
.calculator_input dd {
margin: 20px 0px 0px;
}
.calculator_input dt {
width: 60%;
}
.calculator_input dd {
width: 40%;
}
.calculator_input input {
padding: 1em;
text-align: center;
}
.calculator_input input {
width: 100%;
}
.calculator_action {
display: flex;
justify-content: space-around;
align-items: center;
margin-top: 20px;
}
.calculator_action button {
padding: 1em;
width: 40%;
border: none;
outline: none;
border-radius: 10px;
background-color: #000;
color: #fff;
appearance: none;
cursor: pointer;
}
.calculator_result {
display: flex;
align-items: center;
flex-wrap: wrap;
margin: 0px;
border-bottom: 1px solid #000;
}
.calculator_result dt,
.calculator_result dd {
margin: 0px;
}
.calculator_result dt {
width: 60%;
}
.calculator_result dd {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 40%;
height: 3em;
font-size: 2em;
text-align: center;
}
JavaScript
document.addEventListener('DOMContentLoaded', function() {
const calculator = document.querySelector('.calculator');
const inputItems = calculator.querySelectorAll('.calculator_input input');
for(let i = 0; i < inputItems.length; i++) {
inputItems[i].addEventListener('change', correctInput);
}
const resultItem = calculator.querySelector('.calculator_result dd');
calculator.querySelector('.calculator_action_calc').addEventListener('click', calcInput);
calculator.querySelector('.calculator_action_reset').addEventListener('click', resetAll);
const inputValues = new Array();
function updateInputValues() {
for(let i = 0; i < inputItems.length; i++) {
inputValues[inputItems[i].getAttribute('id')] = parseFloat(inputItems[i].value);
}
}
function resetAll() {
for(let i = 0; i < inputItems.length; i++) {
inputItems[i].value = '';
}
resultItem.textContent = '';
updateInputValues();
}
function correctInput(event) {
const inputValue = event.target.value;
// 数字と小数点以外の文字を削除
const valueNumber = inputValue.replace(/[^0-9.0-9.]/g, '');
// 全角の数字と小数点を半角に変換
event.target.value = valueNumber.replace(/[0-9.]/g, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
}
function checkInput() {
let result = true;
for(let i = 0; i < inputItems.length; i++) {
if(inputItems[i].value === '') {
alert('未入力の項目があります');
result = false;
break;
}
}
return result;
}
function calcInput() {
const checkResult = checkInput();
if(checkResult === false) {
return;
}
updateInputValues();
let result = (inputValues.joutei + inputValues.katei) * inputValues.takasa / 2;
// 小数第一位で四捨五入
result = Math.round(result * 10) / 10;
resultItem.textContent = result;
}
}, false);
計算を行うJavaScriptのコードです。
部分的にコードを解説していきます。
const calculator = document.querySelector('.calculator');
const inputItems = calculator.querySelectorAll('.calculator_input input');
for(let i = 0; i < inputItems.length; i++) {
inputItems[i].addEventListener('change', correctInput);
}
const resultItem = calculator.querySelector('.calculator_result dd');
calculator.querySelector('.calculator_action_calc').addEventListener('click', calcInput);
calculator.querySelector('.calculator_action_reset').addEventListener('click', resetAll);
入力項目のinputや各buttonにイベント処理を登録しています。
const inputValues = new Array();
function updateInputValues() {
for(let i = 0; i < inputItems.length; i++) {
inputValues[inputItems[i].getAttribute('id')] = parseFloat(inputItems[i].value);
}
}
各入力項目の値を配列に格納しています。
id属性に設定された値をキーにした連想配列にまとめているため、「inputValues.takasa」といった書き方で値を参照します。
各入力項目に設定されたデータは文字列データとなっているため、配列データに格納する際、「parseFloat」関数を使って実数として取得しています。
function resetAll() {
for(let i = 0; i < inputItems.length; i++) {
inputItems[i].value = '';
}
resultItem.textContent = '';
updateInputValues();
}
入力された内容の初期化を行う関数です。
function correctInput(event) {
const inputValue = event.target.value;
// 数字と小数点以外の文字を削除
const valueNumber = inputValue.replace(/[^0-9.0-9.]/g, '');
// 全角の数字と小数点を半角に変換
event.target.value = valueNumber.replace(/[0-9.]/g, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
}
入力内容の補正を行う処理です。
input項目に何かしらの値が入力されたときに呼ばれ、数字と小数点以外の文字は削除し、全角の値は半角に変換してinput項目に入れ直しています。
function checkInput() {
let result = true;
for(let i = 0; i < inputItems.length; i++) {
if(inputItems[i].value === '') {
alert('未入力の項目があります');
result = false;
break;
}
}
return result;
}
入力内容のチェックを行う関数です。
今回のサンプルでは、未入力項目のチェックのみを行っています。
function calcInput() {
const checkResult = checkInput();
if(checkResult === false) {
return;
}
updateInputValues();
let result = (inputValues.joutei + inputValues.katei) * inputValues.takasa / 2;
// 小数第一位で四捨五入
result = Math.round(result * 10) / 10;
resultItem.textContent = result;
}
一番重要な計算を行う関数です。
各入力項目の内容を「checkInput」関数でチェックし、問題なければ「updateInputValues」関数で配列データに格納します。
あとは配列データを使って計算を行い、結果を表示します。
ご質問など受け付けています
記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。
ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。