JavaScript で仮想スクロール

仮想スクロールはライブラリなどでReactやVeuなどではありましたが、
Javascriptだけで実装したかったのでchatGPTに教えてもらった時のメモ

```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Virtual Scroll Example</title>
  <style>
    /* スクロール領域のスタイル設定 */
    #container {
      height: 300px;
      overflow-y: scroll;
      border: 1px solid #ccc;
    }
    /* 仮想スクロール領域の高さ */
    #content {
      height: 600px;
    }
  </style>
</head>
<body>

<!-- スクロール領域のコンテナ -->
<div id="container" onscroll="handleScroll()">
  <!-- 仮想スクロール領域 -->
  <div id="content">
    <!-- ここに表示するデータが追加されます -->
  </div>
</div>

<script>
  // HTML要素の取得
  const container = document.getElementById('container');
  const content = document.getElementById('content');
  const pageSize = 10; // 1ページごとのデータ数
  let currentPage = 1; // 現在のページ数

  // ダミーデータの生成
  function generateData(start, end) {
    let data = '';
    for (let i = start; i <= end; i++) {
      data += `<div>Item ${i}</div>`;
    }
    return data;
  }

  // データを表示エリアに追加
  function appendDataToContent(start, end) {
    const newData = generateData(start, end);
    content.innerHTML += newData;
  }

  // スクロールイベントハンドラ
  function handleScroll() {
    const { scrollTop, clientHeight, scrollHeight } = container;

    // スクロールが最下部に達したら新しいデータを読み込む
    if (scrollTop + clientHeight >= scrollHeight - 10) {
      const start = (currentPage - 1) * pageSize + 1;
      const end = currentPage * pageSize;
      appendDataToContent(start, end);
      currentPage++;
    }
  }

  // 最初のデータの読み込み
  appendDataToContent(1, pageSize);
</script>

</body>
</html>
```

1\. スタイル設定: #containerと#contentのスタイルが設定され、#containerはスクロール可能な領域となります。
```
 <style>
    /* スクロール領域のスタイル設定 */
    #container {
      height: 300px;
      overflow-y: scroll;
      border: 1px solid #ccc;
    }
    /* 仮想スクロール領域の高さ */
    #content {
      height: 600px;
    }
  </style>
```

2\.スクロール領域の構造:スクロール領域のコンテナ( #container)と仮想スクロール領域( #content)がHTMLに追加されます。
```
<!-- スクロール領域のコンテナ -->
<div id="container" onscroll="handleScroll()">
  <!-- 仮想スクロール領域 -->
  <div id="content">
    <!-- ここに表示するデータが追加されます -->
  </div>
</div>


```


3\.JavaScript の変数: containerおよびはcontentJavaScript で使用するために HTML 要素を取得します。pageSizeは 1 ページごとのデータ数を示します、currentPageは最新のページ数を示します。
```
const container = document.getElementById('container');
  const content = document.getElementById('content');
  const pageSize = 10; // 1ページごとのデータ数
  let currentPage = 1; // 現在のページ数

```

4\.ダミーデータの生成: generateData関数は指定された範囲のダミーデータを生成します。
```
// ダミーデータの生成
  function generateData(start, end) {
    let data = '';
    for (let i = start; i <= end; i++) {
      data += `<div>Item ${i}</div>`;
    }
    return data;
  }
```
5\.データの表示: appendDataToContent関数は指定された範囲のデータを表示エリアに追加します。
```
// データを表示エリアに追加
  function appendDataToContent(start, end) {
    const newData = generateData(start, end);
    content.innerHTML += newData;
  }
```
6.\スクロールイベントハンドラ: handleScroll関数はスクロールイベントを処理し、最下部に達したら新しいデータを読み込みます。
```
  // スクロールイベントハンドラ
  function handleScroll() {
    const { scrollTop, clientHeight, scrollHeight } = container;

    // スクロールが最下部に達したら新しいデータを読み込む
    if (scrollTop + clientHeight >= scrollHeight - 10) {
      const start = (currentPage - 1) * pageSize + 1;
      const end = currentPage * pageSize;
      appendDataToContent(start, end);
      currentPage++;
    }
  }
```
7.\最初のデータの読み込み:初期表示として最初のデータが読み込まれます。
```
 // 最初のデータの読み込み
  appendDataToContent(1, pageSize);
```