Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

JavaScriptのコールバックがわからない?アニメーション実例でやさしく解説!

3

JavaScriptを学んでいると、「コールバック関数」という言葉に出会うことがよくありますよね。でも、最初はちょっと難しく感じるかもしれません。この記事では、コールバック関数の仕組みを優しく解説して、アニメーションの実例を通して楽しく理解していきましょう!

コールバック関数って何?

コールバック関数とは、別の関数に渡されて、処理が終わった後に呼び出される関数のことです。例えば、「この作業が終わったら次にこれをやる」という感じで、順番に処理を進めたいときに使います。

簡単な例を見てみよう

function greet(name, callback) {
  console.log(`こんにちは、${name}さん!`);
  callback(); // コールバック関数を実行
}

greet("太郎", function() {
  console.log("挨拶が完了しました!");
});

このコードでは、「こんにちは、太郎さん!」と表示した後に「挨拶が完了しました!」というメッセージが出ます。つまり、greet 関数の中でコールバック関数が呼ばれて、後の処理をコントロールしています。

アニメーションでコールバックの動きを体験しよう

アニメーションイメージ

コールバック関数の動きは、少し抽象的に感じることもあります。そこで、順番にフェードインするアニメーションを通じて、コールバックの実際の使い方を確認してみましょう。

コード例:ボックスが順番にフェードイン&フェードアウト

以下のコードでは、4つのボックスが順番にフェードインし、すべて終わったら逆順でフェードアウトします。この動きは、コールバック関数を使って処理を制御しています。

<!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;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
      }

      .box {
        width: 80px;
        height: 80px;
        margin: 10px;
        background-color: #4caf50;
        opacity: 0;
        transform: scale(0.5);
        transition: all 0.7s ease-in-out;
      }

      .box.active {
        opacity: 1;
        transform: scale(1);
      }

      .box.fade-out {
        opacity: 0;
        transform: scale(0.5);
      }
    </style>
  </head>
  <body>
    <!-- アニメーション対象のボックス -->
    <div class="box" id="box1"></div>
    <div class="box" id="box2"></div>
    <div class="box" id="box3"></div>
    <div class="box" id="box4"></div>

    <script>
      // STEP 1: ページロード時にアニメーションを開始
      window.onload = startAnimation;

      // STEP 2: アニメーションを開始する関数
      function startAnimation() {
        console.log("STEP 2: startAnimation関数が呼び出されました");
        animateInSequentially(0); // STEP 3へ遷移
      }

      // STEP 3: フェードインを順番に実行する関数
      function animateInSequentially(index) {
        const boxes = document.querySelectorAll(".box"); // ボックスを取得
        if (index < boxes.length) {
          console.log(`STEP 3: ボックス${index + 1}のフェードインを開始します`);
          animateIn(boxes[index], () => {
            // STEP 4へ遷移
            animateInSequentially(index + 1); // 再びSTEP 3へ遷移(次のボックスをフェードイン)
          });
        } else {
          console.log("STEP 4: すべてのボックスがフェードイン完了、フェードアウトを開始します");
          animateOutSequentially(boxes.length - 1); // STEP 5へ遷移
        }
      }

      // STEP 4: フェードインを実行する関数
      function animateIn(element, callback) {
        console.log("STEP 4: animateIn関数が呼び出されました");
        element.classList.add("active"); // フェードイン開始
        setTimeout(() => {
          console.log("STEP 4: フェードインが完了しました");
          if (callback) {
            callback(); // 呼び出し元の処理に戻る(STEP 3へ遷移)
          }
        }, 700);
      }

      // STEP 5: フェードアウトを逆順に実行する関数
      function animateOutSequentially(index) {
        const boxes = document.querySelectorAll(".box"); // ボックスを取得
        if (index >= 0) {
          console.log(`STEP 5: ボックス${index + 1}のフェードアウトを開始します`);
          animateOut(boxes[index], () => {
            // STEP 6へ遷移
            animateOutSequentially(index - 1); // 再びSTEP 5へ遷移(次のボックスをフェードアウト)
          });
        } else {
          console.log("STEP 6: すべてのボックスがフェードアウト完了しました");
        }
      }

      // STEP 6: フェードアウトを実行する関数
      function animateOut(element, callback) {
        console.log("STEP 6: animateOut関数が呼び出されました");
        element.classList.remove("active"); // フェードイン解除
        element.classList.add("fade-out"); // フェードアウト開始
        setTimeout(() => {
          console.log("STEP 6: フェードアウトが完了しました");
          if (callback) {
            callback(); // 呼び出し元の処理に戻る(STEP 5へ遷移)
          }
        }, 700);
      }
    </script>
  </body>
</html>

コードの動き

  1. フェードインの順番制御

    • startAnimation 関数でアニメーションを開始。

    • animateSequentially 関数がボックスを1つずつフェードインさせ、完了後に次のボックスを実行するためにコールバック関数を使用。

  2. フェードアウトの逆順制御

    • フェードインが完了した後、fadeOutSequentially 関数が逆順でボックスをフェードアウトさせる。

    • フェードアウトもコールバック関数で制御。

  3. コールバックで動きをつなぐ

    • 各ボックスのアニメーションが完了するたびに、次の処理を呼び出すコールバックが実行されます。

コールバック関数が活きる場面

  • 非同期処理の順序制御
    コールバック関数を使えば、アニメーションやAPIの呼び出しなど、非同期処理の順番をコントロールできます。

  • 柔軟な動作変更
    コールバックに異なる関数を渡すことで、処理の内容を簡単に変更できます。

まとめ

コールバック関数は、JavaScriptで処理を順番に進めるための基本的な仕組みです。今回のアニメーションの例を通じて、コールバックの重要性と使い方を体感できたのではないでしょうか。

ただし、コールバック関数を多用するとコードが複雑になる場合があります。次のステップとして、Promise や async/await を学ぶことで、さらに読みやすいコードが書けるようになります。

これからもJavaScriptを楽しみながら学んでいきましょう!

3

もっとルートゼロを知りたいなら

DISCOVER MORE