JavaScriptで英単語学習アプリを作成しよう。

JavaScript

英単語が学習できるWebアプリケーションを作成してみよう。
10種類の動物が日本語が表示されるので英単語入力すると正解が表示される。
10問終わると結果が出力される。

実行例

○実行すると以下のように表示される。

○ぞうは英語でなんだろうか?記憶を頼りに入力していく。

○入力が終わったら「答える」ボタンを押す。すると下部に正解かどうかが表示され次の問題が出題される。(この正解という文字は1.5秒後に消える)

○次の問題を解答する。しろくま??難しい。。。

○間違えてしまった場合は下部に正解が表示される。(この表示も1.5秒後に消える)

○以後繰り返し行い10問を終えると結果を表示して最初に戻る

下のリンクから実際に試すことができる。
https://joytas.net/php/animal/

準備

○任意の場所にanimalappフォルダを作成し、その中にcssフォルダ、jsフォルダ、imagesフォルダを作成する。

○以下のリンクからzipファイルをダウンロードし、解凍後imagesフォルダに格納する。

Let’s challenge

実行例を見ながら、コーディングしてみよう!
試行錯誤している時間こそがあなたを伸ばす。

解答例

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>動物英単語クイズ</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/main.js" defer></script>
</head>
<body>
<div id="container">
  <h1>動物英単語クイズ</h1>
  <p id="ja"></p>
  <label for="entry">英単語を入力してください:</label>
  <input type="text" id="entry">
  <img id="img">
  <button id="btn">答える</button>
  <p id="result"></p>
</div>
</body>
</html>

ポイント解説

<meta name="viewport" content="width=device-width, initial-scale=1.0">:
スマートフォンなどの小さい画面でもレイアウトが崩れないように表示を調整する。

<script src="js/main.js" defer></script>
JavaScriptファイルを読み込むためのタグ。defer属性を使うことで、HTMLの読み込み後にスクリプトが実行される。HTMLの読み込みをブロックしないので結果としてWebサイトの表示が早くなる。

main.css

/* コンテナ全体を中央揃え */
#container {
  display: flex;
  flex-direction: column; /*主軸を縦方向に並べる*/
  align-items: center; /*クロス軸のセンタリング(横方向中央寄せ)*/
  justify-content: center; /* 主軸のセンタリング(縦方向中奥寄せ) */
  height: 100vh; /* 高さを全画面に */
  background-color: #f5f5f5; 
}

/* 日本語表示と入力欄のスタイル */
#ja, #entry {
  font-size: 30px;
  margin: 10px;
}

#entry {
  padding: 5px;
  border: 2px solid #ccc; /* 枠線の追加 */
  border-radius: 5px;
}

/* 画像のスタイル */
#img {
  width: 300px;
  height: 300px;
  margin: 20px;
  object-fit: contain; /* 画像比率を保持 */
  border: 3px solid #ddd;
  border-radius: 10px;
}

/* ボタンのスタイル */
#btn {
  font-size: 30px;
  cursor: pointer;
  padding: 10px 20px;
  background-color: #007bff;
  color: #fff;
  border: none; /* 枠線を消去 */
  border-radius: 5px;
  transition: background-color 0.3s ease; /* ホバーアニメーション */
}

#btn:hover {
  background-color: #0056b3; /* ホバー時の背景色 */
}

/* 結果メッセージのスタイル */
#result {
  transition: 0.5s;
  opacity: 1;
  color: #333;
  font-weight: bold;
}

#result.fade {
  opacity: 0;
  transform: scale(0.95); /* フェードアウト時に少し縮む演出 */
}

ポイント解説

全体のレイアウト

#container {
  display: flex;
  flex-direction: column; /* 主軸を縦方向に並べる */
  align-items: center; /* 横方向中央寄せ */
  justify-content: center; /* 縦方向中央寄せ */
  height: 100vh; /* コンテナを画面全体の高さに広げる */
  background-color: #f5f5f5; /* 背景色を薄いグレーに設定 */
}

レイアウトを中央揃えにするための設定である。display: flexを使い、align-itemsjustify-contentを組み合わせて、要素を縦横ともに画面中央に配置している。

画像スタイル

#img {
  width: 300px;
  height: 300px;
  margin: 20px;
  object-fit: contain; /* 画像の比率を保ちながら表示エリアに収める */
  border: 3px solid #ddd; /* 枠線を追加 */
  border-radius: 10px; /* 枠線の角を丸める */
}

◯画像の表示エリアを固定し、object-fit: containでアスペクト比を崩さずに画像全体を表示している。
◯画像の枠線と角の丸みで、見た目にやわらかい印象を与えるデザインとしている。

結果メッセージのスタイル

#result {
  transition: 0.5s; /* 表示の切り替えをスムーズに */
  opacity: 1;
  color: #333;
  font-weight: bold;
}

#result.fade {
  opacity: 0; /* フェードアウト時に透明になる */
  transform: scale(0.95); /* 少し縮小される動きを追加 */
}

◯正解/不正解メッセージがスムーズにフェードイン・アウトするように、transitionを利用。
◯フェードアウト時に少し縮むようにすることで、自然で洗練されたアニメーション効果を演出している。

main.js

'use strict';

window.onload = () => {
  const animals = [
    ['ぞう', 'elephant', 'elephant.png'],
    ['しろくま', 'polarbear', 'polarbear.png'],
    ['くじら', 'whale', 'whale.png'],
    ['ペンギン', 'penguin', 'penguin.png'],
    ['ライオン', 'lion', 'lion.png'],
    ['カンガルー', 'kangaroo', 'kangaroo.png'],
    ['ひと', 'human', 'human.png'],
    ['いぬ', 'dog', 'dog.png'],
    ['ねこ', 'cat', 'cat.png'],
    ['あり', 'ant', 'ant.png'],
  ];

  const ja = document.getElementById('ja');
  const entry = document.getElementById('entry');
  const img = document.getElementById('img');
  const btn = document.getElementById('btn');
  const result = document.getElementById('result');

  let index = 0;
  let correct = 0;

  const handleAnswer = () => {
    const ans = entry.value.trim().toLowerCase(); // 空白削除と小文字変換
    let msg;

    if (ans === animals[index][1]) {
      correct++;
      msg = '正解!';
    } else {
      msg = `不正解! ${animals[index][0]} の英単語は ${animals[index][1]} です。`;
    }

    if (index === animals.length - 1) {
      msg += `<br>全 ${animals.length} 問中、${correct} 問正解しました。`;
      resetQuiz();
    } else {
      index++;
    }

    displayResult(msg);
    setItem(index);
    entry.focus();
  };

  btn.addEventListener('click', handleAnswer);

  // エンターキーで答えを送信
  entry.addEventListener('keydown', (event) => {
    if (event.key === 'Enter') {
      handleAnswer();
    }
  });

  const displayResult = (msg) => {
    result.innerHTML = msg;
    result.classList.remove('fade');
    setTimeout(() => {
      result.classList.add('fade');
    }, 1500);
  };

  const setItem = (index) => {
    entry.value = '';
    ja.textContent = animals[index][0];
    img.src = 'images/' + animals[index][2];
  };

  const resetQuiz = () => {
    index = 0;
    correct = 0;
  };

  setItem(index);
};

ポイント解説

データ定義

const animals = [
  ['ぞう', 'elephant', 'elephant.png'],
  // ... その他のデータ
];

○クイズのデータを多次元配列で管理している。各要素は「日本語名」「英単語」「画像ファイル名」の3つのデータを含む。
データの構造を統一することで管理が容易になり、拡張性も高い。

イベントハンドラ

btn.addEventListener('click', handleAnswer);

entry.addEventListener('keydown', (event) => {
  if (event.key === 'Enter') {
    handleAnswer();
  }
});

◯ボタンをクリックするかエンターキーを押すことで解答が送信されるよう設定している。
◯エンターキーの対応により、ユーザー体験が向上している。

クイズの解答処理

const handleAnswer = () => {
  const ans = entry.value.trim().toLowerCase(); // 空白削除と小文字変換
  let msg;

  if (ans === animals[index][1]) {
    correct++;
    msg = '正解!';
  } else {
    msg = `不正解! ${animals[index][0]} の英単語は ${animals[index][1]} です。`;
  }

◯入力値をtrimで前後の空白を削除し、toLowerCaseで小文字に変換することで、不要なミスを防止している。
◯正解か不正解かを判断し、適切なメッセージを生成する。

結果表示のアニメーション

const displayResult = (msg) => {
  result.innerHTML = msg;
  result.classList.remove('fade');
  setTimeout(() => {
    result.classList.add('fade');
  }, 1500);
};

result要素に結果メッセージを表示し、1.5秒後にフェードアウトさせる。
視覚的な演出が自然で、クイズの進行を妨げない設計となっている。

総合的な設計のポイント

柔軟性: 配列の内容を変更することでクイズ内容を簡単に拡張可能である。
ユーザー体験: エンターキーやアニメーションなどの工夫で操作が直感的である。
メンテナンス性: 関数を適切に分割し、コードの読みやすさを確保している。

完成

このアプリの動作確認で何度も入力していたら10種類の英単語を完璧マスターしてしまった。なお、シロクマはwhite bearでも問題なく伝わるようだ。polarbearだとpolarが北極を表すので「ホッキョクグマ」のニュアンスに近くなる。

関連記事

コメント

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