【初心者向け】動的コンテンツ公開の仕組みを紐解く

## はじめに
今回は、フロントエンドの動的コンテンツ公開の仕組みについて、まとめてみました。

この説明で、`index.html` と `index.js` の役割と連携、動的コンテンツの公開の仕組み、を理解するのに役立つことを願っています。

`index.html` と `index.js`の2つのファイルが連携することで、ユーザーにとって魅力的で使いやすいWebアプリケーションを構築することができます。JavaScriptフレームワークやライブラリを使用すると、DOM操作やイベント処理をより効率的に行うことができます。

* `index.html` はWebページの静的な構造とコンテンツを提供します。
* `index.js` は、JavaScriptによる操作を通じて、Webページにインタラクティブ性と動的な動きをもたらします。

## `index.html` と `index.js` の連携

1. ユーザーがWebページにアクセスすると、ブラウザはまず `index.html` ファイルを読み込みます。
2. `index.html` ファイル内で `index.js` ファイルが参照されている場合、ブラウザは `index.js` ファイルも読み込みます。
3. `index.js` のコードは実行され、DOMに対する操作やイベントハンドラの設定などが行われます。
4. ユーザーがページ上の要素と操作を行うと、設定されたイベントハンドラが呼び出され、`index.js` のコードが実行されてDOMが更新されます。
5. これらの処理により、Webページは動的に変化し、ユーザーとのインタラクションが可能になります。

### **`index.html` ファイル**
Webアプリケーションの**メインHTMLドキュメント**です。Webページの基本的な構造とコンテンツを定義します。具体的には、見出し、段落、画像、リンクなどの要素が含まれます。通常、`<script>` タグを使用して `index.js` ファイルを**参照**します。これは、ブラウザにHTMLコンテンツの解析後にJavaScriptコードを読み込むよう指示します。


例:指定された要素と機能を組み合わせて、メモを追加するシンプルなウェブアプリケーションの例を示します。このアプリケーションでは、ユーザーが入力フィールドにテキストを入力し、「追加」ボタンをクリックすると、そのテキストがリストに追加されます。
```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>メモアプリ</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>メモアプリ</h1>
  <div>
    <input type="text" id="text-input" placeholder="メモを入力してください">
    <button id="add-button">追加</button>
  </div>
  <ul id="memo-list"></ul>

  <script src="index.js"></script>
</body>
</html>
```

### **`index.js` ファイル**

アプリケーションの**ロジック**を含むJavaScriptファイルです。ブラウザ内のHTMLドキュメントの表現である **DOM（Document Object Model）** とやり取りします。`index.js` のJavaScript関数を使用することで、`index.html` ドキュメントの内容を**動的に操作**することができます。DOM を操作することで、Web ページの要素を追加、削除、変更したり、スタイルを変更したりすることができます。

__JavaScriptでイベントリスナーを追加して(ユーザーが入力フィールドにテキストを入力し、「追加」ボタンをクリックすると、そのテキストがリストに追加される)動作を実現しています。__
```javascript
// DOMが完全に読み込まれた後に実行されるようにする
document.addEventListener('DOMContentLoaded', function() {
  const textInput = document.getElementById('text-input');
  const addButton = document.getElementById('add-button');
  const memoList = document.getElementById('memo-list');

  // メモを追加する関数
  function addMemo() {
    const text = textInput.value;
    if (text.trim() === '') {
      return; // 空の入力は無視する
    }

    // 新しいリストアイテムを作成
    const li = document.createElement('li');

    // 新しい段落要素を作成してテキストを設定
    const p = document.createElement('p');
    p.textContent = text;

    // リストアイテムに段落要素を追加
    li.appendChild(p);

    // リストに新しいリストアイテムを追加
    memoList.appendChild(li);

    // 入力フィールドをクリア
    textInput.value = '';
  }

  // ボタンにイベントリスナーを追加する
  addButton.addEventListener('click', addMemo);
});
```

## DOM操作の基本的な操作

1. **要素を取得する** `document.getElementById()`, `document.querySelector()`, `document.getElementsByTagName()`などのメソッドを使って、操作したいHTML要素を取得します。

2. **要素を操作する** 取得した要素に対して、`innerHTML`, `textContent`, `setAttribute()`, `appendChild()`, `removeChild()`などのプロパティやメソッドを使って、属性を変更したり、子要素を追加・削除したりすることができます。

3. **要素を追加する** `document.createElement()` メソッドを使って要素を作成し、`appendChild()` メソッドを使って親要素に追加します。

| 操作の種類 | メソッド | 説明 |
| --- | --- | --- |
| **要素の取得** | `document.getElementById(id)` | 指定したIDを持つ要素を取得 |
| | `document.getElementsByClassName(className)` | 指定したクラス名を持つ要素のリストを取得 |
| | `document.getElementsByTagName(tagName)` | 指定したタグ名を持つ要素のリストを取得 |
| | `document.querySelector(selector)` | 指定したCSSセレクタに一致する最初の要素を取得 |
| | `document.querySelectorAll(selector)` | 指定したCSSセレクタに一致するすべての要素のリストを取得 |
| **要素の作成** | `document.createElement(tagName)` | 指定したタグ名の新しい要素を作成 |
| **要素の追加** | `parentElement.appendChild(newElement)` | 親要素に新しい子要素を追加 |
| | `parentElement.insertBefore(newElement, referenceElement)` | 親要素の指定した子要素の前に新しい要素を挿入 |
| **要素の削除** | `parentElement.removeChild(childElement)` | 親要素から指定した子要素を削除 |
| **要素の属性操作** | `element.setAttribute(name, value)` | 要素に新しい属性を追加または既存の属性を更新 |
| | `element.getAttribute(name)` | 要素の指定した属性の値を取得 |
| | `element.removeAttribute(name)` | 要素の指定した属性を削除 |
| **要素の内容操作** | `element.innerHTML` | 要素のHTML内容を取得または設定 |
| | `element.textContent` | 要素のテキスト内容を取得または設定 |
| **要素のスタイル変更** | `element.style.cssText` | 要素のスタイルを直接設定 |
| **要素の非表示** | `element.style.display = 'none'` | 要素を非表示にする |
| **要素のアニメーション** | `element.style.transition` | 要素をアニメーションさせるためのプロパティ |

**注意事項**

**要素が存在するかどうかを確認する** 要素を取得する前に、`getElementById()` や `querySelector()` メソッドの戻り値が `null` ではないことを確認する必要があります。
**イベントハンドラを使用する** ユーザーの操作に応じて DOM を操作する場合は、イベントハンドラを使用する必要があります。
**パフォーマンスを考慮する** 大量の要素を操作したり、複雑な操作を行うと、パフォーマンスが低下する可能性があります。
**セキュリティ** DOM操作を悪用して、XSSなどの脆弱性を攻撃される可能性があります。

本記事はQmonus Value Streamの投稿キャンペーン記事です。