2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript初心者がDOM操作を学びながら「割り勘計算アプリ」を作ってみる

2
Last updated at Posted at 2026-10-09

はじめに

こんにちは、株式会社Techoesの C (入社から半年目の初心者エンジニア)と申します!

現在、HTML・CSS・JavaScriptを学習しています。

前回の記事では、Codexを使ってゲームを作った経験を紹介しました。今回は先輩からの提案をきっかけに、自分でコードを書きながら、簡単なWebアプリを作ってみました。

最初は電卓を考えていましたが、日常でも使えるものにしたいと思い、「割り勘計算アプリ」を作ることにしました。

この記事では、アプリを作る中でつまずいたことや、学んだことを紹介します。

2. 今回作る割り勘計算アプリ

image.png

お会計の金額と人数を入力して「計算」ボタンを押すと、1人あたりの金額が表示されるアプリです。集める金額の合計と、お会計との差額も表示します。

1人あたりの金額は、1円未満を切り上げています。例えば、3,500円を3人で割ると1人あたり1,167円になり、合計で1円多く集まります。

入力欄が空の場合や、0・負数・小数を入力した場合は、エラーメッセージが表示されます。「クリア」ボタンを押すと、入力内容と計算結果をリセットできます。

HTML・CSS・JavaScriptを使って作りました。スマートフォンでも使えるように、画面幅に合わせて余白や文字サイズを調整しています。

3. HTMLで入力欄とボタンを作る

まず、お会計金額と人数の入力欄を作りました。その下に「計算」「クリア」のボタンと、結果を表示するエリアを用意しました。

<div class="app">
    <h1>割り勘計算アプリ</h1>
    <p>お会計の金額と人数から、1人分の金額を計算します。</p>

    <div class="field">
        <!-- labelは入力欄の説明。forを入力欄のidに合わせる -->
        <label for="money">お会計金額(円):</label>
        <!-- 数値の入力欄を作成し、idで要素を識別する -->
        <input type="number" id="money">
    </div>

    <div class="field">
        <label for="people">人数(人):</label>
        <input type="number" id="people">
    </div>

    <div class="actions">
        <button class="calculate-btn" onclick="calculate();">計算</button>
        <button class="clear-btn" onclick="clearInput();">クリア</button>
    </div>

    <div id="result">まだ計算していません</div>
    <p class="note">1人分の金額は、1円未満を切り上げます。</p>
</div>

入力欄にはtype="number"を指定し、金額にはid="money"、人数にはid="people"を付けました。後からJavaScriptで、それぞれの入力欄を取得するために使います。また、labelのforを入力欄のIDと合わせて、説明文と入力欄を結び付けています。

ボタンにはonclickを設定し、「計算」を押すとcalculate()、「クリア」を押すとclearInput()が実行されるようにしました。それぞれの関数の中身は、次の章から説明します。

結果を表示するエリアにはid="result"を付けました。最初は「まだ計算していません」と表示し、計算後にJavaScriptで結果に書き換えます。

class="field"とclass="actions"は、後からCSSで入力欄やボタンの配置を整えるために付けています。

4. JavaScriptで入力値を取得して計算する

計算ボタンにはonclick="calculate();"を設定しています。ボタンを押すとcalculate()関数が実行され、入力値の取得から計算結果の表示までを行います。

const moneyInput = document.querySelector("#money");
const peopleInput = document.querySelector("#people");
const money = Number(moneyInput.value);
const people = Number(peopleInput.value);

document.querySelector()を使って、金額と人数の入力欄を取得します。#moneyと#peopleは、HTMLで設定したIDに対応しています。

次に、.valueで入力内容を読み取ります。入力欄にtype="number"を指定していても、取得する値は文字列なので、Number()で数値に変換します。

最初は、querySelector()で入力欄の内容を直接取得できると思っていました。実際に使ってみて、取得するのは入力欄の要素そのもので、入力された値を読むには.valueが必要だと分かりました。

これらの変数は宣言後に再代入しないため、constを使いました。

const amountPerPerson = Math.ceil(money / people);
const collectedTotal = amountPerPerson * people;
const extra = collectedTotal - money;

result.innerHTML =
    "1人あたりの金額<br>" +
    "<span class='amount'>" + amountPerPerson + " 円</span><br>" +
    "集める金額の合計:" + collectedTotal + " 円<br>" +
    "お会計との差額:" + extra + " 円";

金額と人数を取得した後、お会計金額を人数で割って、1人あたりの金額を計算します。今回新しく学んだMath.ceil()を使い、1円未満を切り上げました。詳しい使い方は第6章で紹介します。

続いて、1人あたりの金額に人数を掛けて、集める金額の合計を求めます。そこから元のお会計金額を引いて、差額を計算します。

結果表示エリアは、document.querySelector("#result")で取得しています。最後に、result.innerHTMLで結果表示エリアの内容を更新します。<br>で改行し、1人あたりの金額を<span class='amount'>で囲んで、CSSで大きく表示できるようにしました。

5. 入力チェックとクリア機能を追加する

入力チェック

計算処理だけでは、未入力の場合や、金額・人数に0を入力した場合も計算が実行されます。そこで、計算前に入力をチェックし、金額と人数はどちらも0より大きい整数に限定しました。

if (money <= 0) {
    result.className = "error";
    result.innerHTML = "金額は0より大きい数値を入力してください";
    return;
}

if (!Number.isInteger(money)) {
    result.className = "error";
    result.innerHTML = "金額は整数(円単位)で入力してください";
    return;
}

入力欄が空の場合、Number("")は0になります。そのため、<= 0で未入力・0・負数をチェックできます。小数はNumber.isInteger()で判定します。先頭の!で判定結果を反転させ、整数ではない場合にエラーとして扱います。

入力に問題があれば、result.innerHTMLでメッセージを表示し、returnで関数の処理を終了します。これにより、その後の計算は実行されません。

また、result.className = "error"でエラー用のスタイルを適用し、メッセージを赤く表示します。計算を実行するたびに、最初にresult.className = ""でエラー用のスタイルを解除し、入力を修正した後は通常の表示に戻るようにしました。

クリア機能

function clearInput() {
    const moneyInput = document.querySelector("#money");
    const peopleInput = document.querySelector("#people");
    const result = document.querySelector("#result");

    moneyInput.value = "";
    peopleInput.value = "";
    result.className = "";
    result.innerHTML = "まだ計算していません";
}

クリアボタンを押すと、2つの入力欄の.valueを空文字列にして、入力内容を消します。同時にエラー用のスタイルを解除し、結果表示エリアを「まだ計算していません」に戻して、もう一度入力できるようにしました。

6. 端数の切り上げと差額の計算

お会計金額が人数で割り切れるとは限りません。例えば、3,500円を3人で割ると、1人あたりの金額は約1166.666…円になります。そのため、端数をどう扱うかを考える必要がありました。

今回新しく学んだMath.ceil()は、数値を整数に切り上げるメソッドです。例えば、Math.ceil(1166.666…)の結果は1167になります。もともと整数の場合は、そのままの値になります。

const amountPerPerson = Math.ceil(money / people);
const collectedTotal = amountPerPerson * people;
const extra = collectedTotal - money;

まず、お会計金額を人数で割り、Math.ceil()で切り上げて、1人あたりの金額を求めます。次に、その金額に人数を掛けて集金額の合計を計算し、元のお会計金額を引いて差額を求めます。

今回の例では、次のようになります。

項目 金額
お会計金額 3,500円
1人あたりの金額 1,167円
3人分の集金額 3,501円
差額 1円

切り上げることで集金額が不足するのを防げますが、お会計金額より少し多く集める場合があります。そのため、いくら多く集めることになるのか分かるように、差額も画面に表示しました。

image.png

7. CSSで画面を整える

機能ができた後、CSSで入力欄やボタンの余白を整えました。計算ボタンとクリアボタンはFlexboxで横並びにし、計算ボタンにflex: 1を指定して、残りのスペースを埋めるようにしました。

結果表示エリアは薄い緑色にし、1人あたりの金額を大きく太字で表示しました。入力に問題がある場合は、errorクラスで赤い表示に切り替えています。

スマートフォン向けには、@media (max-width: 500px)で余白と見出しの文字サイズを小さくしました。Chromeのデバイスモードを使い、狭い画面でも入力欄・ボタン・結果が収まることを確認しました。

@media (max-width: 500px) {
    body {
        padding: 12px;
    }

    .app {
        margin: 12px auto;
        padding: 20px;
    }

    h1 {
        font-size: 24px;
    }
}

image.png

8. 動作確認と、つまずいた点

機能ができた後、正常な入力に加えて、未入力・0・負数・小数の場合も確認しました。制作中には、ボタンを押しても画面が変わらないことがありました。

関数名が原因でボタンが動かなかった

最初は計算用の関数をclick()と名付け、ボタンにonclick="click();"を設定していました。名前を合わせれば動くと思っていましたが、ボタンを押しても結果表示エリアが更新されませんでした。

以下は、当時の問題を再現したコードです。

<button class="calculate-btn" onclick="click();">計算</button>
<button class="clear-btn" onclick="clear();">クリア</button>

<script>
    function click() {
        // 計算処理(省略)
    }

    function clear() {
        // クリア処理(省略)
    }
</script>

原因を調べると、ボタンにはもともとclick()というメソッドがあり、この書き方では自分で作った関数ではなく、そちらが呼び出されていました。

関数名をcalculate()に変更し、ボタンのonclickも合わせて修正すると、正常に動くようになりました。

<button class="calculate-btn" onclick="calculate();">計算</button>
<button class="clear-btn" onclick="clearInput();">クリア</button>

<script>
    function calculate() {
        // 計算処理(省略)
    }

    function clearInput() {
        // クリア処理(省略)
    }
</script>

クリア機能でも、clear()という名前が既存のdocument.clear()と重なり、自分で作った関数が呼び出されませんでした。こちらもclearInput()に変更して解決しました。

この経験から、関数名は「クリック」のような操作名よりも、「計算する」「入力を消す」のように、何をする関数なのか分かる名前にしようと思いました。

CSSで画面を整えるのにも苦戦した

CSSの調整にも時間がかかりました。基本的な書き方は練習していましたが、実際に画面を作ると、入力欄やボタン、結果をどう配置すれば使いやすくなるのか迷いました。

まずは余白と大きさから調整し、入力欄の説明を上に置き、2つのボタンをFlexboxで横並びにしました。計算結果では、1人あたりの金額を大きくして、重要な情報が目に入りやすいようにしました。

今回、CSSのプロパティの使い方を知っていても、それらを組み合わせて画面を整えるには、まだ練習が必要だと感じました。

9. まとめ

今回の割り勘計算アプリ制作では、これまで学んだJavaScriptの基礎を組み合わせて、実際に操作できるアプリを作りました。学習と復習を通して、コードの意味も少しずつ分かるようになり、入力値の取得からチェック、結果の表示までの流れを理解できました。

DOM操作では、「HTML要素を取得すること」と「入力された値を読み取ること」の違いが分かりました。また、文字の更新、スタイルの切り替え、入力欄のクリアも練習できました。新しくNumber.isInteger()とMath.ceil()を学び、letとconstの使い分けも整理できました。

機能はまだ少なく、調べたり質問したりする場面もありましたが、自分でコードを書きながら理解を深められたことが、今回一番の収穫です。今後も練習を続け、計算履歴などの機能も追加してみたいと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?