JavaScriptで簡易チャットアプリを作成して学んだこと


# 目次
[はじめに](#はじめに)
[学んだこと](#学んだこと)
　[1.ボタンと入力値取得の流れ](#1-ボタンと入力値取得の流れ)
　[2.メッセージ出力の流れ](#2-メッセージ出力の流れ)
[ソース](#ソース)
[さいごに](#さいごに)

# はじめに
今回は「テッククルー / プログラミング学習」さんの下記動画をもとに、JavaScriptで簡易チャットアプリの作成をおこないました。

https://youtube.com/playlist?list=PLey1r5U24UpHGgnY7usVly9DbpvX2Ioid&si=DBouAWlqqGUlVd02

具体的な作成方法についてはこちらの動画で説明されているため、この記事では今回の簡易チャットアプリ作成で「学んだこと」を記録と復習のためにまとめてみようと思います。

※ これまでJavaScriptで作成したものの記事はこちら↓

https://qiita.com/osakanaaaa/items/d6a1b6184ad412e2a182

https://qiita.com/osakanaaaa/items/e4b596f44feedf1b99f8

# 学んだこと

## 1. ボタンと入力値取得の流れ
◆ 送信ボタン取得
```html:html
<button id="sendBtn" class="btn btn-primary" type="button">送信</button>
```
```js:js
// htmlのidをもとに送信ボタン取得
let sendBtn = document.getElementById('sendBtn');
```
◆ 送信ボタンがクリックされたときに動く関数作成
```js:js
sendBtn.addEventListener('click', function() {
})
```
```addEventListener()```
通常の記載方法は「対象要素.addEventListener(種類, 関数, false)」だが、今回は無名関数を設定しているため「対象要素.addEventListener(種類, function() {})」と記載（falseは省略）

※上記関数内に、これより下に記載の処理追加

◆ 入力欄取得
```html:html
<input id="inputMessage" type="text" class="form-control" placeholder="メッセージを入力してください" >
```
```js:js
// htmlのidをもとにinputタグを保存
let inputMessage = document.getElementById('inputMessage');
```
◆ 入力値取得
```js:js
// inputタグがもつ画面の入力値を変数に保存
let messageText = inputMessage.value;
```
◆ 入力値が空の場合に処理を中断
```js:js
// 入力値が空かチェック
if (messageText == '') {
    // 以降の処理実行されない
    return;
}
```
◆ 送信ボタンが押された時に、入力欄の入力値をリセットする
```js:js
// 入力欄が持っている値を空文字で上書き
inputMessage.value = '';
```
[ページ上部へ戻る](#目次)

## 2. メッセージ出力の流れ
#### メッセージ用のdivタグ作成
◆ メッセージ用のdivタグを作成する関数作成
```js:js
// メッセージ用のdivタグを作成する関数
function createMessageBox() {
}
```
※ 上記関数内に、これより下に記載の処理追加

◆ divタグを作成
```js:js
let messageBox = document.createElement('div');
```
自分が送信者の場合「box-right」というクラスをdivに追加
相手が送信者の場合「box-left」というクラスをdivに追加
※ ここでは分岐の記載を省略しているため、実際のソースは[ソース](#ソース)を参照
```js:js
// 要素に対してクラスを設定
messageBox.classList.add('box-right');
messageBox.classList.add('box-left');
```
#### メッセージ用のpタグ作成
◆ メッセージ用のpタグを作成する関数作成
```js:js
function createMessage(messageText) {
}
```
※ 入力値は下記のように既に取得済みのため、上記引数の「messageText」には画面入力値が渡ってくる
※ 上記関数内に、これより下に記載の処理追加

```js:js
let messageText = inputMessage.value;
```
◆ pタグのテキストに画面の入力値を設定
```js:js
// 文字設定する時はtextContent使用
message.textContent = messageText;
```
◆ pタグに「message-box」というクラスを追加
```js:js
message.classList.add('message-box');
```
自分が送信者の場合、pタグに「green」というクラスを追加
相手が送信者の場合、pタグに「white」というクラスを追加
※ ここでは分岐の記載を省略しているため、実際のソースは[ソース](#ソース)を参照
```js:js
// 要素に対してクラスを設定
message.classList.add('green');
message.classList.add('white');
```
#### divタグにpタグを追加
```js:js
// messageBoxの子要素として追加するためappendChildを使用
messageBox.appendChild(message);
```
```appendChild()```
親要素に子要素を追加し、HTMLタグの追加をおこなう

#### チャット画面のdivに新規メッセージのdivを追加

◆ チャット画面のdivタグを取得
```html:html
<div id="room">
</div>
```
```js:js
// htmlのidをもとにチャット画面のdivタグを取得
let room = document.getElementById('room');
```
◆ チャット画面のdivに新規メッセージのdivを追加
```js:js
// roomの子要素として追加するためappendChildを使用
room.appendChild(messageBox);
```
※ pタグ（変数名：message）が設定されているdivタグ（変数名：messageBox）を、チャット画面のdivタグ（変数名：room）に追加

[ページ上部へ戻る](#目次)

# ソース
<details><summary>HTML</summary><div>

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <link rel="stylesheet" href="./assets/css/style.css">
  <title>Chat</title>
</head>
<body>
  <!-- 青い背景色になってるチャットアプリの画面 -->
  <div id="room">

    <div class="box-left">
      <p class="message-box white">こんにちは</p>
    </div>

    <div class="box-right">
      <p class="message-box green">こんにちは</p>
    </div>

  </div>

  <div class="input-group chat-input">
    <input id="inputMessage" type="text" class="form-control" placeholder="メッセージを入力してください" >
    <div class="input-group-append">
      <button id="sendBtn" class="btn btn-primary" type="button">送信</button>
    </div>
  </div>

  <script src="./assets/js/app.js"></script>
</body>
</html>
```
</div></details>

<details><summary>JavaScript</summary><div>

```js:app.js
// -- 変数を用意（true： 自分が送信/false： 相手が送信） --
// 送信者が自分かどうか保存する変数
let isMyself = true;
// ---------- 送信ボタンの取得 ----------
// idをもとに送信ボタン取得
let sendBtn = document.getElementById('sendBtn');

// ---- 送信ボタンがクリックされたときの処理 ----
sendBtn.addEventListener('click', function() {
    // ---------- 入力欄を取得 ----------
    // idをもとにinputタグを保存
    let inputMessage = document.getElementById('inputMessage');
    // ---------- 入力値を取得 ------------
    // inputタグがもつ画面の入力値を変数に保存
    let messageText = inputMessage.value;
    // --- 入力値が空の場合に処理を中断 ---
    // 入力値が空かチェックする
    if (messageText == '') {
        // 以降の処理実行されない
        return;
    }

    // ------- メッセージ用のdivタグを作成する  -------
    // messageBoxにdivを入れる
    let messageBox = createMessageBox();
    // ------- メッセージ用のpタグを作成する  -------
    let message = createMessage(messageText);
    // ------- divにpタグを追加する -------
    // messageBoxの子要素として追加するためappendChildを使用
    messageBox.appendChild(message);
    
    // ---- チャット画面のdivタグを取得する ----
    let room = document.getElementById('room');
    // -- チャット画面のdivに新規メッセージのdivを追加する --
    // 動作確認時Safariだとうまくいかず、Chromeで確認
    room.appendChild(messageBox);

    // -- 送信ボタンが押された時に、入力欄の入力値をリセットする --
    // 入力欄が持っている値を空文字で上書き
    inputMessage.value = '';

    // ------- 送信されるたびに送信者を変更 -------
    if (isMyself) {
        // 自分が送信者の場合、次の送信者を相手にする
        isMyself = false;
    } else {
        // 相手が送信者の場合、次の送信者を自分にする
        isMyself = true;
    }

    // ------- メッセージ用のdivタグを作成する  -------
    function createMessageBox() {
        // ---------- divを作成 ----------
        let messageBox = document.createElement('div');
        // 誰が送信者かチェック
        if (isMyself) {
            // 自分が送信者の場合
            // 「box-right」というクラスをdivに追加（要素に対してクラスを設定）
            messageBox.classList.add('box-right');
        } else {
            // 相手が送信者の場合
            // 「box-left」というクラスをdivに追加（要素に対してクラスを設定）
            messageBox.classList.add('box-left');
        }

        return messageBox;
    }

    // ------- メッセージ用のpタグを作成する  -------
    // pタグ作るとき文字の設定が必要
    function createMessage(messageText) {
        // ---------- pタグを作成 ----------
        let message = document.createElement('p');
        // pタグのテキストに画面の入力値を設定
        // 文字設定する時はtextContent使用
        message.textContent = messageText;
        // pタグに「message-box」というクラスを追加
        message.classList.add('message-box');
        // 誰が送信者かチェック
        if (isMyself) {
            // 自分が送信者の場合
            // pタグに「green」というクラスを追加
            message.classList.add('green');
        } else {
            // 相手が送信者の場合
            // pタグに「white」というクラスを追加
            message.classList.add('white');
        }

        return message;
    }
})

```
</div></details>

※完成したものはこのようになります↓

![スクリーンショット 2024-07-20 14.12.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558666/93cfe472-522a-7976-a535-3251b487cad6.png)

[ページ上部へ戻る](#目次)

# さいごに
今回はJavaScriptでの簡易チャットアプリ作成を通して学んだことをアウトプットしました。
今回の作成で、画面からの入力値をどのように受け取り、処理し、出力していくかの流れを学ぶことができました。
最後まで目を通していただきありがとうございました。私の記録が誰かの役に立つと嬉しいです。。