はじめに (Web開発初学者向け!モールス信号アプリで学ぶDOM操作と文字列処理)

この記事は、JavaScriptの基本的な文法は理解しているものの、実際にWebアプリケーションを開発する際のDOM操作やイベント処理にまだ慣れていない方を主な対象としています。また、簡単なWebアプリを自作してみたいプログラミング初学者の方にもおすすめです。

この記事を読むことで、HTMLとJavaScriptを使ってユーザーインターフェースを備えたシンプルなWebアプリを構築する方法がわかります。特に、JavaScriptのオブジェクトを使ったデータの管理方法や、ユーザーが入力した複数文字をループ処理で変換し、結果を表示するまでの一連の流れを実践的に学ぶことができます。今回は、身近な題材である「モールス信号変換」をテーマに、楽しくプログラミングの応用力を高めましょう。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 * HTMLの基本的なタグ(div, textarea, buttonなど)の記述方法 * CSSによる基本的なスタイリングの指定方法 * JavaScriptの変数、関数、条件分岐、ループ(for文など)、オブジェクトの基本的な使い方

モールス信号変換アプリの基礎と設計

本記事で開発するモールス信号変換アプリは、ユーザーが入力した日本語・英語の文字をモールス信号に、あるいはモールス信号を文字に変換する機能を提供します。特に、一文字だけでなく、入力された「文字列全体」を正しく変換できることを目指します。

モールス信号の基本ルール

モールス信号は、短点(または.)、長点(または-)、そしてそれらの組み合わせによって文字や数字を表します。基本的なルールとして、以下の要素が挙げられます。

  • 文字内の符号: 短点と長点の組み合わせ(例: Aは.-
  • 文字間隔: 1つの短点の長さ分の間隔
  • 単語間隔: 7つの短点の長さ分の間隔(またはスラッシュ/で区切ることも多い)

今回のアプリでは、入力の簡易化のため、モールス信号の符号は.-を使用し、文字間は半角スペース1つ、単語間は半角スペース3つ、または/(スラッシュ)で区切るルールを採用します。

アプリケーションの設計方針

このアプリを構築するにあたり、以下の設計を考えます。

  1. UI(ユーザーインターフェース):

    • 文字入力用テキストエリア
    • モールス信号入力用テキストエリア(または、入出力共通のエリア)
    • 「文字 → モールス信号」変換ボタン
    • 「モールス信号 → 文字」変換ボタン
    • 変換結果表示エリア
  2. データ構造:

    • 文字とモールス信号の対応関係を保持するデータ(JavaScriptのオブジェクトを利用)
    • 「A」が「.-」であるように、キーと値のペアで構成。
  3. 変換ロジック:

    • 文字 → モールス信号: 入力された文字列を一文字ずつ取り出し、対応するモールス信号に変換して連結する。単語間のスペースや不明な文字の処理も考慮。
    • モールス信号 → 文字: 入力されたモールス信号列をスペースやスラッシュで区切り、一つ一つの符号に対応する文字に変換して連結する。未知の符号の処理も考慮。

これらの設計を元に、次章で具体的な実装を進めていきます。

多文字対応!モールス信号変換アプリの実装

ここでは、上記で設計したモールス信号変換アプリを実際にHTMLとJavaScriptを使って実装していきます。一つずつ手順を踏んで、完成を目指しましょう。

ステップ1: HTMLの骨格とシンプルなCSSでUIを整える

まずは、ユーザーが入力したり結果を見たりするためのHTML要素を配置します。今回は非常にシンプルなUIに留めます。

index.html

Html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>モールス信号変換アプリ</title> <style> body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; } .container { max-width: 800px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } h1 { text-align: center; color: #0056b3; } .input-section, .output-section { margin-bottom: 20px; } label { display: block; margin-bottom: 8px; font-weight: bold; } textarea { width: calc(100% - 20px); min-height: 100px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; resize: vertical; } .buttons { display: flex; justify-content: center; gap: 15px; margin-bottom: 20px; } button { padding: 10px 20px; font-size: 16px; background-color: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button:hover { background-color: #0056b3; } .note { font-size: 0.9em; color: #666; text-align: center; margin-top: 20px; } </style> </head> <body> <div class="container"> <h1>モールス信号変換アプリ</h1> <div class="input-section"> <label for="textInput">変換したい文字を入力してください:</label> <textarea id="textInput" placeholder="例: HELLO WORLD"></textarea> </div> <div class="buttons"> <button id="toMorseBtn">→ モールス信号へ変換</button> <button id="toTextBtn">← 文字へ変換</button> </div> <div class="output-section"> <label for="outputResult">変換結果:</label> <textarea id="outputResult" readonly></textarea> </div> <p class="note"> モールス信号から文字へ変換する際は、単語間はスペース3つ、またはスラッシュ(/)で区切ってください。<br> 例: `.... . .-.. .-.. --- .-- --- .-. .-.. -..` (HELLO WORLD)<br> 例: `.... . .-.. .-.. --- / .-- --- .-. .-.. -..` (HELLO WORLD) </p> </div> <script src="script.js"></script> </body> </html>

ステップ2: JavaScriptでモールス信号の辞書と基本ロジックを作成する

次に、JavaScriptファイル(script.js)を作成し、モールス信号の対応辞書と、変換の基盤となるロジックを定義します。

script.js

Javascript
// モールス信号の対応辞書(文字 -> モールス符号) const charToMorse = { 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '.': '.-.-.-', ',': '--..--', '?': '..--..', '\'': '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.', ' ': '/' // スペースはスラッシュで区切るか、単語間の区切りとして扱う }; // モールス信号の対応辞書(モールス符号 -> 文字) // charToMorseから逆引き辞書を生成することも可能だが、ここでは明示的に定義 const morseToChar = {}; for (const char in charToMorse) { morseToChar[charToMorse[char]] = char; } // 特殊な区切り文字の定義 morseToChar['/'] = ' '; // スラッシュをスペースとして扱う // DOM要素の取得 const textInput = document.getElementById('textInput'); const outputResult = document.getElementById('outputResult'); const toMorseBtn = document.getElementById('toMorseBtn'); const toTextBtn = document.getElementById('toTextBtn');

ステップ3: 複数文字の変換ロジックを実装する

ここが本記事の核心部分です。入力された文字列(またはモールス信号列)を、1文字ずつ(または1符号ずつ)処理し、最終的な結果を生成するロジックを記述します。

文字列 → モールス信号への変換ロジック

Javascript
function convertToMorse() { let inputText = textInput.value.toUpperCase(); // 入力を大文字に統一 let morseOutput = []; let currentWord = []; for (let i = 0; i < inputText.length; i++) { const char = inputText[i]; if (char === ' ') { // 単語の区切りを検出 if (currentWord.length > 0) { // 現在の単語のモールス符号を結合して追加 morseOutput.push(currentWord.join(' ')); currentWord = []; // 単語をリセット } // 単語間の区切りとしてスラッシュを追加(または複数スペース) morseOutput.push('/'); // スペースはスラッシュで表現 } else { const morseChar = charToMorse[char]; if (morseChar) { currentWord.push(morseChar); } else { // 辞書にない文字は変換できないことを示す currentWord.push('?'); } } } // 最後の単語があれば追加 if (currentWord.length > 0) { morseOutput.push(currentWord.join(' ')); } outputResult.value = morseOutput.join(' '); // 全てのモールス符号をスペースで区切って表示 }

この関数では、入力されたテキストを1文字ずつループで処理します。 * toUpperCase()で入力を大文字に統一し、辞書検索の失敗を防ぎます。 * スペース(単語の区切り)を検出した場合は、それまでの文字をモールス符号に変換したものを一旦区切り、新しい単語の処理を開始します。単語間は/で区切るようにしています。 * 辞書に存在する文字は対応するモールス符号に変換し、存在しない文字は?として処理します。 * 最終的に、変換されたモールス符号の配列をスペースで連結して出力します。

モールス信号 → 文字列への変換ロジック

Javascript
function convertToText() { // 入力値を半角スペース3つをスラッシュに置換してから、スペースで分割 // これにより、複数スペースでの単語区切りにも対応 let inputText = textInput.value.replace(/ /g, ' / ').trim(); // 3つ以上のスペースを / に変換 let morseCodes = inputText.split(' '); // スペースで分割 let textOutput = []; for (let i = 0; i < morseCodes.length; i++) { const morseCode = morseCodes[i]; if (morseCode === '') continue; // 空文字はスキップ const char = morseToChar[morseCode]; if (char) { textOutput.push(char); } else { // 辞書にないモールス符号は変換できないことを示す textOutput.push('?'); } } outputResult.value = textOutput.join(''); // 全ての文字を連結して表示 }

この関数では、入力されたモールス信号列をスペースで分割し、1つの符号ずつ処理します。 * まず、入力されたモールス信号列の「3つの連続したスペース」をスラッシュ(/)に置換しています。これは、モールス信号の単語間隔(スペース3つ)を統一的に処理するためです。 * その後、文字列を半角スペースで分割し、個々のモールス符号を取得します。 * 各モールス符号を逆引き辞書morseToCharで検索し、対応する文字に変換します。 * 辞書に存在しない符号は?として処理されます。 * 最終的に、変換された文字の配列を連結して出力します。

ステップ4: イベントリスナーを設定し、機能連携

最後に、作成した変換関数をボタンクリック時に実行されるようにイベントリスナーを設定します。

Javascript
// イベントリスナーの設定 toMorseBtn.addEventListener('click', convertToMorse); toTextBtn.addEventListener('click', convertToText);

これで、script.jsの全コードが完成し、HTMLと連携して動作するようになります。

ハマった点やエラー解決

実装中に遭遇しやすい問題と、その解決策について解説します。

問題1: 大文字・小文字の区別で変換が失敗する

状況: ユーザーが「hello world」と入力した場合、charToMorse辞書には大文字しか定義されていないため、変換結果が???のようになる。

解決策: 入力された文字列をtoUpperCase()メソッドで強制的に大文字に変換することで、辞書とのマッチングを確実にします。これにより、ユーザーがどちらで入力しても正しく変換されるようになります。

Javascript
// convertToMorse関数の冒頭で let inputText = textInput.value.toUpperCase(); // これを追加

問題2: 未知の文字やモールス信号が入力された場合の処理

状況: 辞書に定義されていない文字(例: 日本語、特殊記号)や、無効なモールス信号(例: .-.-のような存在しない組み合わせ)が入力された場合に、どう表示すべきか。

解決策: 辞書検索の結果がundefined(見つからない)だった場合に、特定のプレースホルダー文字(例: ?[不明]など)を出力するようにロジックを追加します。これにより、変換できなかった部分が明確になり、ユーザー体験が向上します。

Javascript
// convertToMorse関数内 if (morseChar) { currentWord.push(morseChar); } else { currentWord.push('?'); // 辞書にない文字は '?' と表示 } // convertToText関数内 if (char) { textOutput.push(char); } else { textOutput.push('?'); // 辞書にないモールス符号は '?' と表示 }

問題3: 文字間の区切りと単語間の区切りの表現

状況: モールス信号では文字間と単語間で間隔の長さが異なります。アプリでこれをどう表現し、どう解釈させるか。

解決策: 今回の実装では、以下のルールを設けました。 * 文字 → モールス信号: 各文字のモールス符号は半角スペース1つで区切ります。単語の区切りにはスラッシュ(/)を使用します。 * 例: HELLO WORLD.... . .-.. .-.. --- / .-- --- .-. .-.. -.. * モールス信号 → 文字: 入力されたモールス信号列を半角スペースで分割し、各符号を変換します。特に、単語間の区切りとして用いられることが多いスラッシュ(/)や、3つの連続した半角スペース()も単語の区切りとして認識し、結果のテキストでは通常のスペースに変換します。

convertToText関数の以下の部分で対応しています。

Javascript
let inputText = textInput.value.replace(/ /g, ' / ').trim(); // 3つ以上のスペースを / に変換 // ... morseToChar['/'] = ' '; // スラッシュをスペースとして扱う

これにより、ユーザーがモールス信号を入力する際に、単語の区切りをスラッシュでも、あるいはスペース3つでも表現できるようになり、柔軟性が増します。

まとめ

本記事では、HTMLとJavaScriptを使用して、複数文字に対応したモールス信号変換アプリを構築しました。

  • JavaScriptオブジェクトによる辞書データの管理: 文字とモールス信号の対応関係をcharToMorsemorseToCharという2つのオブジェクトで効率的に管理しました。
  • ループ処理と文字列操作による複数文字の変換: forループを使って入力された文字列(またはモールス信号列)を1文字(または1符号)ずつ処理し、split(), join(), toUpperCase(), replace()などの文字列操作メソッドを駆使して変換ロジックを実装しました。
  • DOM操作とイベントリスナーによるUI連携: getElementById()でHTML要素を取得し、addEventListener()でボタンのクリックイベントを監視することで、ユーザーのアクションに応じた処理を実行させました。

この記事を通して、Webアプリケーションの基本的な開発フロー、特にユーザー入力の取得、データの変換処理、そして結果の表示という一連の流れを体験し、JavaScriptの応用力を深めることができたのではないでしょうか。

今後は、音声でのモールス信号再生機能を追加したり、リアルタイムで変換結果が表示されるように改善したりと、さらに発展的な内容にも挑戦してみてください。

参考資料