JavaScript | 1 日 30 分 × 7 日アプリ学習超初級編:文字を表示するアプリ

JavaScript
スポンサーリンク

6日目のゴール

6日目のキーワードも同じく
「画面を書き換える」 ですが、今日は

同じ情報を「違う見せ方」で表示する
ボタンで「表示モード」を切り替える
画面全体を“まとめて描き直す”感覚をつかむ

ここまでをゴールにします。

5日目までは、「新しい行を追加する」方向の書き換えでした。
6日目は、「今あるデータを、どう見せるかを切り替える」
いわば「表示フィルタ」の入り口をやります。


今日作るミニアプリのイメージ

「メッセージ履歴+表示モード切り替えアプリ」

今日のアプリは、こんなイメージです。

メッセージを追加していく(5日目と同じ)
「通常表示」と「逆順表示」を切り替えられる
「全部大文字表示」モードにも切り替えられる

つまり、「中身は同じメッセージたち」なのに、
ボタンを押すと「見え方」が変わるアプリです。

ここで大事なのは、

データ(メッセージの中身)は変えない
画面の描き方だけを変える

という考え方です。


土台となる HTML を用意する

入力・履歴・表示モードボタン

まずは HTML を組み立てます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>文字を表示するアプリ 6日目</title>
</head>
<body>
    <h1>メッセージ履歴+表示モードアプリ</h1>

    <p>メッセージを入力して「追加」ボタンを押すと、下に履歴として追加されます。</p>

    <input id="messageInput" type="text" placeholder="メッセージを入力">
    <button id="addButton">追加</button>
    <button id="clearButton">全部消す</button>

    <h2>表示モード</h2>
    <p id="modeDisplay">現在のモード:通常表示</p>
    <button id="normalModeButton">通常表示</button>
    <button id="reverseModeButton">逆順表示</button>
    <button id="upperModeButton">全部大文字表示</button>

    <h2>メッセージ履歴</h2>
    <div id="historyArea">
        <p>まだメッセージはありません。</p>
    </div>

    <script src="app.js"></script>
</body>
</html>

役割を整理するとこうなります。

messageInput / addButton / clearButton
これは5日目と同じ、「メッセージを追加・削除」する部分です。

modeDisplay
今どの表示モードかを表示する場所です。

normalModeButton / reverseModeButton / upperModeButton
表示モードを切り替えるボタンです。
押されたら「画面の描き方」を変えます。

historyArea
メッセージ履歴を表示する箱です。
ここを「モードに応じて描き直す」のが今日の主役です。


JavaScript の基本部分を書く

要素取得と「データの置き場所」

app.js に、まずは要素取得とデータ用の配列を書きます。

const messageInputElement = document.getElementById("messageInput");
const addButtonElement = document.getElementById("addButton");
const clearButtonElement = document.getElementById("clearButton");

const modeDisplayElement = document.getElementById("modeDisplay");
const normalModeButtonElement = document.getElementById("normalModeButton");
const reverseModeButtonElement = document.getElementById("reverseModeButton");
const upperModeButtonElement = document.getElementById("upperModeButton");

const historyAreaElement = document.getElementById("historyArea");

// メッセージを配列で持つ
const messages = [];

// 表示モードを表す変数
// "normal" / "reverse" / "upper" のどれか
let currentMode = "normal";
JavaScript

ここで今日の重要ポイントが2つ出てきます。

messages 配列
5日目は「画面に直接追加」していましたが、
6日目は「データを配列にためておいて、画面はあとから描く」形にします。
これが「データ」と「表示」を分ける第一歩です。

currentMode
4日目でやった「モード」の考え方を、
今度は「表示モード」に使います。
この値によって、画面の描き方を変えます。


「画面を描き直す」関数を作る

データから画面を作る、ただ一つの場所

今日いちばん大事な関数がこれです。

function renderHistory() {
    if (messages.length === 0) {
        historyAreaElement.innerHTML = "<p>まだメッセージはありません。</p>";
        return;
    }

    historyAreaElement.textContent = "";

    if (currentMode === "normal") {
        for (let i = 0; i < messages.length; i++) {
            const p = document.createElement("p");
            p.textContent = messages[i];
            historyAreaElement.appendChild(p);
        }
    } else if (currentMode === "reverse") {
        for (let i = messages.length - 1; i >= 0; i--) {
            const p = document.createElement("p");
            p.textContent = messages[i];
            historyAreaElement.appendChild(p);
        }
    } else if (currentMode === "upper") {
        for (let i = 0; i < messages.length; i++) {
            const p = document.createElement("p");
            p.textContent = messages[i].toUpperCase();
            historyAreaElement.appendChild(p);
        }
    }
}
JavaScript

この関数の役割を、丁寧に分解します。

messages.length === 0 のとき
まだ1件もメッセージがないときは、
「まだメッセージはありません。」を表示して終わりです。

historyAreaElement.textContent = “”;
いったん中身を全部消します。
ここから「今のモードに合わせて、全部描き直す」からです。

currentMode === “normal” のとき
配列の先頭から順番に、
messages[i] をそのまま表示します。
これが「通常表示」です。

currentMode === “reverse” のとき
配列の最後から逆向きに、
messages[i] を表示します。
これが「逆順表示」です。

currentMode === “upper” のとき
配列の先頭から順番に、
messages[i].toUpperCase() を表示します。
toUpperCase は「全部大文字にする」メソッドです。

ここで超重要なのは、

どのモードでも「元の messages 配列は変えていない」
変えているのは「画面にどう出すか」だけ

という点です。


メッセージを追加する処理を書く

データを更新してから、画面を描き直す

次に、「追加」ボタンの処理を書きます。

addButtonElement.addEventListener("click", function () {
    const text = messageInputElement.value;

    if (text === "") {
        alert("メッセージが空です。何か入力してください。");
        return;
    }

    messages.push(text);

    messageInputElement.value = "";
    messageInputElement.focus();

    renderHistory();
});
JavaScript

流れはこうです。

入力欄から文字を取り出す
空なら警告を出して終わり
空でなければ messages 配列に push する
入力欄を空にしてフォーカスを戻す
最後に renderHistory() で画面を描き直す

ここでのポイントは、

「画面に直接追加する」のではなく
「配列に追加してから、画面は renderHistory に任せる」

という構造にしていることです。

これにより、

「表示モードを変えたとき」も
「メッセージを追加したとき」も

どちらも「最後に renderHistory を呼ぶだけ」で済むようになります。


「全部消す」処理を書く

データも画面もリセットする

「全部消す」ボタンの処理はこう書きます。

clearButtonElement.addEventListener("click", function () {
    messages.length = 0;
    renderHistory();
});
JavaScript

messages.length = 0;
配列の長さを0にすることで、中身を全部消しています。
(超初級編では「こうすると全部消える」と覚えておけばOKです)

そのあと、やはり renderHistory(); で画面を描き直します。
messages が空なので、「まだメッセージはありません。」表示に戻ります。

ここでも、

「データを変える」
「画面を描き直す」

という2ステップを意識しています。


表示モードを切り替える処理を書く

状態を変えてから、画面を描き直す

次に、表示モードボタンの処理を書きます。

まずは「モード表示」を更新する関数を作ります。

function updateModeDisplay() {
    if (currentMode === "normal") {
        modeDisplayElement.textContent = "現在のモード:通常表示";
    } else if (currentMode === "reverse") {
        modeDisplayElement.textContent = "現在のモード:逆順表示";
    } else if (currentMode === "upper") {
        modeDisplayElement.textContent = "現在のモード:全部大文字表示";
    }
}
JavaScript

そして、ボタンのイベントを登録します。

normalModeButtonElement.addEventListener("click", function () {
    currentMode = "normal";
    updateModeDisplay();
    renderHistory();
});

reverseModeButtonElement.addEventListener("click", function () {
    currentMode = "reverse";
    updateModeDisplay();
    renderHistory();
});

upperModeButtonElement.addEventListener("click", function () {
    currentMode = "upper";
    updateModeDisplay();
    renderHistory();
});
JavaScript

ここでの流れは、4日目と同じです。

currentMode を変える
モード表示を更新する
画面(履歴)を描き直す

これで、

メッセージを追加する
→ データが増える → renderHistory で今のモードに合わせて表示

表示モードを変える
→ currentMode が変わる → renderHistory で同じデータを違う見せ方で表示

という動きになります。


6日目の app.js をまとめて見る

全体像を通して確認する

ここまでのコードを1つにまとめると、こうなります。

const messageInputElement = document.getElementById("messageInput");
const addButtonElement = document.getElementById("addButton");
const clearButtonElement = document.getElementById("clearButton");

const modeDisplayElement = document.getElementById("modeDisplay");
const normalModeButtonElement = document.getElementById("normalModeButton");
const reverseModeButtonElement = document.getElementById("reverseModeButton");
const upperModeButtonElement = document.getElementById("upperModeButton");

const historyAreaElement = document.getElementById("historyArea");

// メッセージの配列
const messages = [];

// 表示モード
let currentMode = "normal";

// 履歴を画面に描き直す
function renderHistory() {
    if (messages.length === 0) {
        historyAreaElement.innerHTML = "<p>まだメッセージはありません。</p>";
        return;
    }

    historyAreaElement.textContent = "";

    if (currentMode === "normal") {
        for (let i = 0; i < messages.length; i++) {
            const p = document.createElement("p");
            p.textContent = messages[i];
            historyAreaElement.appendChild(p);
        }
    } else if (currentMode === "reverse") {
        for (let i = messages.length - 1; i >= 0; i--) {
            const p = document.createElement("p");
            p.textContent = messages[i];
            historyAreaElement.appendChild(p);
        }
    } else if (currentMode === "upper") {
        for (let i = 0; i < messages.length; i++) {
            const p = document.createElement("p");
            p.textContent = messages[i].toUpperCase();
            historyAreaElement.appendChild(p);
        }
    }
}

// モード表示を更新する
function updateModeDisplay() {
    if (currentMode === "normal") {
        modeDisplayElement.textContent = "現在のモード:通常表示";
    } else if (currentMode === "reverse") {
        modeDisplayElement.textContent = "現在のモード:逆順表示";
    } else if (currentMode === "upper") {
        modeDisplayElement.textContent = "現在のモード:全部大文字表示";
    }
}

// メッセージ追加
addButtonElement.addEventListener("click", function () {
    const text = messageInputElement.value;

    if (text === "") {
        alert("メッセージが空です。何か入力してください。");
        return;
    }

    messages.push(text);

    messageInputElement.value = "";
    messageInputElement.focus();

    renderHistory();
});

// 全部消す
clearButtonElement.addEventListener("click", function () {
    messages.length = 0;
    renderHistory();
});

// 表示モード切り替え
normalModeButtonElement.addEventListener("click", function () {
    currentMode = "normal";
    updateModeDisplay();
    renderHistory();
});

reverseModeButtonElement.addEventListener("click", function () {
    currentMode = "reverse";
    updateModeDisplay();
    renderHistory();
});

upperModeButtonElement.addEventListener("click", function () {
    currentMode = "upper";
    updateModeDisplay();
    renderHistory();
});

// 最初の表示を整える
updateModeDisplay();
renderHistory();
JavaScript

この状態で動かすと、

メッセージを追加していく
→ 通常表示なら上から順に並ぶ
→ 逆順表示にすると、新しいものが上に来る
→ 大文字表示にすると、全部が大文字で表示される

という、「同じデータをいろんな見せ方で表示する」アプリになります。


6日目で絶対に押さえておきたいこと

「データ」と「表示」を分ける感覚

今日いちばん大事なのは、この構造です。

データは messages 配列にためておく
画面は renderHistory という“ただ一つの関数”で描く
何か変化があったら、最後に renderHistory を呼ぶ

これによって、

「追加された」「消された」「モードが変わった」
どんな変化が起きても、
「データを変える → 画面を描き直す」という
同じパターンで考えられるようになります。

画面を書き換える
というテーマの中でも、
今日は「部分的にいじる」のではなく
「一度消して、全部描き直す」というスタイルを体験しました。

実は、現代の多くのフレームワーク(React など)も
この「データから画面を毎回描き直す」考え方をベースにしています。


もし余裕があればやってみてほしいこと

表示モードを自分で増やしてみる

例えば、こんなモードを足せます。

「文字数つき表示モード」
[5文字] こんにちは のように表示するモード

やることはシンプルです。

currentMode に "length" を追加する
updateModeDisplay にその表示を足す
renderHistory に "length" のときの描き方を足す

length モードの例は、こんな感じです。

} else if (currentMode === "length") {
    for (let i = 0; i < messages.length; i++) {
        const p = document.createElement("p");
        const len = messages[i].length;
        p.textContent = "[" + len + "文字] " + messages[i];
        historyAreaElement.appendChild(p);
    }
}
JavaScript

こうやって遊んでいるうちに、
「画面を書き換える」が
「データをどう見せるかをデザインする」感覚に変わっていきます。


6日目のまとめ

6日目で、あなたは

メッセージを配列(データ)として持つ
画面は「データ+モード」から毎回描き直す
表示モードを変えることで、同じデータを違う見せ方にする

という、「画面を書き換える」の中でも
一段レベルの高いパターンに触れました。

7日目は、ここまでの

入力
履歴
モード
表示の描き直し

をまとめて、「自分用の小さな“メッセージビューアアプリ”」として
形にしていきます。

タイトルとURLをコピーしました