（ハンズオン用）HTMLをJavaScriptで効率よく組み立てる方法


この記事は[31億市場!?  チャットの作り方[1日コース]](https://qiita.com/st5757/items/c2c5cf21c97fe242a4c0)の連載3コマ目です。

（初歩的な内容なので、ベテランの方は読み飛ばてください）


[前回作ったコード](https://firebasestorage.googleapis.com/v0/b/chatservicesample.appspot.com/o/day2.zip?alt=media&token=12256585-0382-4b76-a913-548c447daf7f)を元に、修正を加えていきます。
よかったらハンズオンでやってみてください。

雰囲気的には↓こんな感じのことをします。
いわゆる、javascriptでDOMを操作する作業です。
（ごめんなさい、そういやjQueryも使ってます）

<img width="720" alt="from_js_to_html.png" src="https://qiita-image-store.s3.amazonaws.com/0/13827/bc8ec607-fd10-e06e-62da-cd1ed0ce3d58.png">

要は、htmlに直接書いていたコードをjavascript側から描画しています。

なぜこんな面倒臭いことをするかというと、場合によって表示するものを変えたいことがあります。
今回の例だと、吹き出しは場合によって表示されるものが異なりますよね。
その場合はいつも同じものを表示することができないため、このようにJavascriptでhtmlを作る必要があります。
（なお、今回はチャットの枠もJavascriptで作っています）

## 今回やること
前回作ったUIのhtmlをJavascript（jQuery）で動的に組み立てるようにしてみます。

## これができると何が良い？
業務ではjavascriptから動的にhtmlを組み立てたり、変更を加えたりすることはよくあります。
ただし、１行１行描画すると効率が悪いのでhtmlを塊にして描画していきます。

## htmlをjavascript側に移す
じゃあ早速やっていきます。
まずは`index.html`と同階層に`js`フォルダをつくり、その中に`bmesse.js`をつくります。
フォルダの構成はこうなります。

```
/
├─index.html
├─css
│   └─bmesse.css
└─js
   └─bmesse.js
```
今後javascritファイルは全てこの`js`フォルダに置くことにします。
その方がファイルが増えた時に見通しがいいので。
`index.html`のコードでは、body要素の最下部で`bmesse.js`を読み込みます。
Viewの操作はjQueryで効率的に行いたいので、jQueryも読み込んでおきます。
（今回はGoogleにホストされているもの利用）

```html
・・・
<body>
    ・・・
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="js/bmesse.js"></script>
</body>
</html>
```

### ●cssもまとめる
javascriptファイル同様に、cssもまとめます。
`index.html`と同階層に`style`フォルダをつくり、その中に`bmesse.css`を移動。cssの置き場所が変わったので、`index.html`も書き換えます。

```html
<head>
    ・・・
    <link type="text/css" rel="stylesheet" href="style/bmesse.css" />
</head>

```

### ●bmesse.jsの中身を作る
```javascript
"use strict";//厳格モードで実装

/** 
 * id=your_containerに対してチャットUIを組み込む 
 **/
$(document).ready(function() {//htmlの描画が終わったら、処理を実行する記述

    //文字列(html要素)を格納できる配列を定義
    var chatDom =[];
    //文字列（この場合は引数のdom）を配列の要素として格納できる関数
    var p = function(dom){
        chatDom.push(dom);
    };

    //配列の要素として一つ一つ格納していき、最後にjoin関数で結合する
    //チャットの外側部分①
    p('<div id="bms_messages_container">');

        //ヘッダー部分②
        p('<div id="bms_chat_header">');
            p('<div id="bms_chat_user_status">');
                p('<div id="bms_status_icon">●</div>')
                p('<div id="bms_chat_user_name">ユーザー</div>');
            p('</div>');
        p('</div>');
              //タイムライン部分③
        p('<div id="bms_messages">');

            //メッセージ１（左側）
            p('<div class="bms_message bms_left">');
                p('<div class="bms_message_box">');
                    p('<div class="bms_message_content">');
                        p('<div class="bms_message_text">ほうほうこりゃー便利じゃないか</div>');
                    p('</div>');
                p('</div>');
            p('</div>');
            p('<div class="bms_clear"></div>');

            //メッセージ２（右側）
            p('<div class="bms_message bms_right">');
                p('<div class="bms_message_box">');
                    p('<div class="bms_message_content">');
                        p('<div class="bms_message_text">うん、まあまあいけとるな</div>');
                    p ('</div>');
                p('</div>');
            p('</div>');
            p('<div class="bms_clear"></div>');
        p('</div>');

        // テキストボックス、送信ボタン④
        p('<div id="bms_send">');
            p('<textarea id="bms_send_message"></textarea>');
            p('<div id="bms_send_btn">送信</div>');
        p('</div>');

        //jQueryのappend関数を使って、your_containerの直下にhtml要素を書き加える
        $('#your_container').append(chatDom.join(''));
});
```
これで、javascriptでhtmlを動的に書き換えることができたので、`index.html`に書かれているものはいらなくなりました。
削除すると`index.html`はこんな感じになります。
スッキリしましたね。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link type="text/css" rel="stylesheet" href="style/bmesse.css" />
    <title>チャットサンプル</title>
</head>
<body>
    <h3 id="me" user_id="1">あなたはユーザー1です</h3>
    <h3 id="partner">相手</h3>
    <div id="users">
        <button class="user" user_id="2">ユーザー2</button>
    </div>
    <br>
    <div id="your_container">
        <!-- ここにbmesseが動的に挿入される -->
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="js/bmesse.js"></script>
</body>
</html>
```
`index.html`を開いてチャットのUIが表示されればOKです。
出来上がったソースコードは[ここ](https://firebasestorage.googleapis.com/v0/b/chatservicesample.appspot.com/o/day3.zip?alt=media&token=c248ccd9-5902-470d-a8b0-89beefe512d3)に置いておきますね。

吹き出しは実際には動的に書き加えられるものなので、まだまだ不十分ですね。
なので次回「はじめてのFirebase（データベースの基礎）」でそこを作っていきます。
Firebaseのデータベースを使って、リアルタイムに吹き出しを表示できるようにしていきます。

ではまた次回〜♪

（※連載一覧は[こちら](https://qiita.com/st5757/items/c2c5cf21c97fe242a4c0#機能としてはこんな感じです)）