カテゴリー: JavaScript

  • ハンバーガーメニューの作り方

    ハンバーガーメニューの作り方

    スマートフォンサイトでは必ず使うハンバーガーメニュー。
    本記事では以下の機能をすべて実装します。

    • 三本線が「×」に変形するアニメーション
    • メニューが右からスライドイン
    • 背景が暗くなるオーバーレイ
    • 背景クリックでメニューを閉じる
    • メニュー表示中はスクロール禁止
    My Menu

    WordPressサイトでも利用できるよう、HTML / CSS / JS を分けて解説します。


    1. ファイル構成

    WordPressでは
    「HTML → テンプレート内」「CSS → 追加CSS」「JS → 外部読み込み」
    で実装可能ですが、学習用としてディレクトリ構造も提示します。

    lesson9/
    ├── index.html
    ├── style.css
    └── script.js
    

    2. HTML構造

    最も基本的なハンバーガーメニューの構造です。

    <header class="header">
      <div class="logo">MySite</div>
    
      <div class="hamburger" id="hamburger">
        <span></span><span></span><span></span>
      </div>
    
      <nav class="nav" id="nav">
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">Service</a></li>
          <li><a href="#">Price</a></li>
          <li><a href="#">Access</a></li>
        </ul>
      </nav>
    
      <div class="overlay" id="overlay"></div>
    </header>
    

    3. CSS(アニメーション・スライドイン・オーバーレイ)

    /* 基本設定 */
    body {
      margin: 0;
      font-family: "Yu Gothic", sans-serif;
    }
    
    /* ハンバーガーアイコン(3本線) */
    .hamburger {
      width: 30px;
      cursor: pointer;
      position: relative;
      z-index: 1001;
    }
    
    .hamburger span {
      display: block;
      height: 3px;
      background: #333;
      margin: 6px 0;
      transition: 0.3s;
    }
    
    /* active時(三本線 → × に変形) */
    .hamburger.active span:nth-child(1) {
      transform: translateY(9px) rotate(45deg);
    }
    .hamburger.active span:nth-child(2) {
      opacity: 0;
    }
    .hamburger.active span:nth-child(3) {
      transform: translateY(-9px) rotate(-45deg);
    }
    
    /* ナビゲーション(初期は右の外) */
    .nav {
      position: fixed;
      top: 0;
      right: -100%;
      width: 70%;
      height: 100vh;
      background: #fff;
      padding-top: 80px;
      transition: 0.4s ease;
      z-index: 1000;
    }
    
    /* ナビ表示 */
    .nav.show {
      right: 0;
    }
    
    /* オーバーレイ(背景暗くする) */
    .overlay {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.4);
      opacity: 0;
      pointer-events: none;
      transition: 0.3s;
      z-index: 999;
    }
    
    .overlay.show {
      opacity: 1;
      pointer-events: all;
    }
    
    /* スクロールを止める */
    .no-scroll {
      overflow: hidden;
      height: 100vh;
    }
    

    4. JavaScript(解説コメント付き)

    「模写学習」がしやすいよう、上に正解コメント/下に自分で書く行、という形式です。

    /* =============================
       第9章:ハンバーガーメニュー
    ============================= */
    
    /* 要素取得 */
    const ham = document.querySelector("#hamburger");
    const nav = document.querySelector("#nav");
    const overlay = document.querySelector("#overlay");
    
    /* ハンバーガークリックで開閉 */
    ham.addEventListener('click', () => {
      ham.classList.toggle("active");
      nav.classList.toggle('show');
      overlay.classList.toggle('show');
      document.body.classList.toggle('no-scroll');
    });
    
    /* オーバーレイクリックで閉じる */
    overlay.addEventListener('click', () => {
      ham.classList.remove('active');
      nav.classList.remove('show');
      overlay.classList.remove('show');
      document.body.classList.remove('no-scroll');
    });
    

    5. 動作の仕組み(技術解説)

    ハンバーガー → × の変形

    CSSの nth-child()transform を使う。
    2本目を消し、1本目・3本目を回転させることで×を作る。

    ナビが右からスライドイン

    初期状態では right: -100%
    .show を付けると right: 0 に移動し、CSS transition がアニメーションする。

    背景が暗くなる(overlay)

    .show によって opacitypointer-events を切り替え、
    半透明の黒背景を操作可能にする。

    スクロール停止

    メニュー表示時に

    .no-scroll {
      overflow: hidden;
    }
    

    が付与され、ページ全体のスクロールが無効化される。


    6. チェックリスト

    項目動作確認
    三本線 → × に変形する必須
    ナビが右から開く必須
    背景が暗くなる必須
    背景タップで閉じる必須
    開いている間はスクロール不可実務必須
    スマホ実機で動く実務必須

    7. 応用(実務でよく使う改良)

    左から出すタイプ

    .navrightleft に変更するだけ。

    フェード+スライド

    opacity を追加するとより自然な動きになる。

    上から出るメニュー

    レスポンシブデザインでよく使われる。


    8. まとめ

    このハンバーガーメニューは、
    企業サイト・美容室・飲食店・LP など、
    ほぼすべてのスマホサイトに必要になるUIです。

    今回のコードはそのまま実務で使える構成のため、
    WordPressサイトに組み込めばすぐに動作します。

  • JavaScript だけで作るサムネイル切り替えギャラリー

    JavaScript だけで作るサムネイル切り替えギャラリー

    Web制作では、サムネイルにマウスを乗せるとメイン画像が切り替わるギャラリーがよく使われます。この記事ではライブラリを使わず、純粋な JavaScript だけで実装する方法を解説します。

    初心者でも「なぜ動くのか」が理解できるように構成しています。


    完成イメージ

    今回つくるギャラリーは次のように動きます。

    ・メイン画像が一枚表示される
    ・その下にサムネイルが複数並ぶ
    ・サムネイルにマウスを乗せるとメイン画像が切り替わる
    ・切り替え時にふわっと透明度が上がるアニメーションが動く

    視覚的に気持ち良い操作感を実現します。


    HTML(基本構造)

    <section class="image-gallery">
    
      <div class="main-image">
        <img src="main.jpg" alt="">
      </div>
    
      <ul class="thumbnails">
        <li><img src="thumb1.jpg" alt=""></li>
        <li><img src="thumb2.jpg" alt=""></li>
        <li><img src="thumb3.jpg" alt=""></li>
        <li><img src="thumb4.jpg" alt=""></li>
      </ul>
    
    </section>
    

    HTML のポイント

    要素役割
    section.image-galleryギャラリー全体の枠
    .main-imageメイン画像の表示エリア
    .thumbnailsサムネイル一覧。ここに触れると切り替わる

    CSS(見やすいレイアウト)

    .image-gallery {
      max-width: 500px;
      margin: auto;
    }
    
    .main-image img {
      width: 100%;
      display: block;
      object-fit: cover;
    }
    
    .thumbnails {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
      gap: 8px;
      list-style: none;
      padding: 0;
      margin-top: 12px;
    }
    
    .thumbnails img {
      width: 100%;
      cursor: pointer;
      transition: opacity 0.3s;
    }
    
    .thumbnails img:hover {
      opacity: 0.7;
    }
    

    CSS のポイント解説

    ・image-gallery で全体幅を制限して中央に配置
    ・main-image img は縦横比を崩さず大きく表示
    ・thumbnails は CSS Grid でサムネイルを自動整列
    ・サムネイル hover 時に透明度が下がり操作している感が出る


    JavaScript(サムネイルに触れたら画像を切り替える)

    document.addEventListener('DOMContentLoaded', () => {
    
      const mainImage = document.querySelector('.main-image img');
    
      const thumbs = document.querySelectorAll('.thumbnails img');
    
      thumbs.forEach(thumb => {
    
        thumb.addEventListener('mouseover', (e) => {
    
          mainImage.src = e.target.src;
    
          mainImage.animate(
            { opacity: [0, 1] },
            { duration: 400, easing: "ease-out" }
          );
    
        });
      });
    });
    

    JavaScript の詳しい解説

    DOMContentLoaded とは

    document.addEventListener('DOMContentLoaded', () => { ... });
    

    HTML が読み終わったタイミングでコードを実行するためのイベントです。画像や要素がまだ読み込まれていない段階で実行するとエラーになりやすいため必須です。


    メイン画像を取得する

    const mainImage = document.querySelector('.main-image img');
    

    main-image 内の img を一枚だけ取得します。
    mainImage.src に値を入れることで画像が瞬時に切り替わります。


    すべてのサムネイルを取得する

    const thumbs = document.querySelectorAll('.thumbnails img');
    

    .thumbnails 内のすべての img をまとめて取得します。
    これを forEach でひとつずつ処理します。


    サムネイルにマウスを乗せた瞬間の処理

    thumb.addEventListener('mouseover', (e) => {
    

    ・mouseover はマウスが乗った瞬間に反応
    ・e.target は乗ったサムネイル画像そのもの


    メイン画像を切り替える

    mainImage.src = e.target.src;
    

    サムネイルの画像 URL をメイン画像に代入するだけで切り替えができます。


    ふわっと明るくなるフェードアニメーション

    mainImage.animate(
      { opacity: [0, 1] },
      { duration: 400, easing: "ease-out" }
    );
    

    ・opacity 0 → 1 に変化
    ・duration は 400ms(0.4秒)
    ・easing を使い柔らかく表示

    CSS を書かずに JavaScript でもアニメーションが実行できます。


    WordPress で使う場合の配置

    種類貼る場所
    HTMLカスタム HTML ブロック
    CSS追加 CSS または style タグ
    JavaScriptscript タグで記事内に記述

    テーマに依存しないため、どの環境でも動作します。


    まとめ:このギャラリーで学べること

    ・DOM 取得(querySelector / querySelectorAll)
    ・イベント処理(addEventListener)
    ・event.target の扱い
    ・img.src を使った画像の差し替え
    ・Web Animations API(element.animate)

    初心者の実践練習として最適な構成になっています。

  • JavaScript だけで作るサムネイル切り替えギャラリー

    JavaScript だけで作るサムネイル切り替えギャラリー

    Web制作では、サムネイルにマウスを乗せるとメイン画像が切り替わるギャラリーがよく使われます。この記事では、ライブラリを使わずに JavaScript だけで実装する方法を説明します。初心者でも仕組みが理解できるように構成しています。


    完成イメージ

    今回のギャラリーは次のように動きます。

    ・メイン画像が一枚表示される
    ・サムネイルが複数並ぶ
    ・サムネイルにマウスを乗せるとメイン画像が切り替わる
    ・切り替え時に透明度が変化するアニメーションが動く

    視覚的に自然で使いやすい構成です。

    Profile

    Person A

    寿司職人

    Profile

    Person B

    デザイナー

    Profile

    Person C

    医者

    Profile

    Person D

    消防隊員

    Profile

    Person E

    ニート

    Profile

    Person F

    教師


    HTML

    <section class="image-gallery">
    
      <div class="main-image">
        <img src="main.jpg" alt="">
      </div>
    
      <ul class="thumbnails">
        <li><img src="thumb1.jpg" alt=""></li>
        <li><img src="thumb2.jpg" alt=""></li>
        <li><img src="thumb3.jpg" alt=""></li>
        <li><img src="thumb4.jpg" alt=""></li>
      </ul>
    
    </section>
    

    HTML のポイント

    要素説明
    image-galleryギャラリー全体の囲い
    main-imageメイン画像の表示部分
    thumbnailsマウスを乗せて切り替えを行うサムネイル一覧

    CSS

    .image-gallery {
      max-width: 500px;
      margin: auto;
    }
    
    .main-image img {
      width: 100%;
      display: block;
      object-fit: cover;
    }
    
    .thumbnails {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
      gap: 8px;
      list-style: none;
      padding: 0;
      margin-top: 12px;
    }
    
    .thumbnails img {
      width: 100%;
      cursor: pointer;
      transition: opacity 0.3s;
    }
    
    .thumbnails img:hover {
      opacity: 0.7;
    }
    

    CSS のポイント

    ・image-gallery はギャラリー全体の大きさを制御し、中央に寄せる
    ・main-image img は縦横比を保ったまま表示
    ・thumbnails は CSS Grid で自動整列
    ・サムネイルにホバーした時に透明度を変えて操作性を出す


    JavaScript

    document.addEventListener('DOMContentLoaded', () => {
    
      const mainImage = document.querySelector('.main-image img');
    
      const thumbs = document.querySelectorAll('.thumbnails img');
    
      thumbs.forEach(thumb => {
    
        thumb.addEventListener('mouseover', (e) => {
    
          mainImage.src = e.target.src;
    
          mainImage.animate(
            { opacity: [0, 1] },
            { duration: 400, easing: "ease-out" }
          );
    
        });
      });
    });
    

    JavaScript の解説

    DOMContentLoaded を使う理由は、HTML が読み込まれて構造が準備できてからスクリプトを実行するためです。要素がまだ読み込まれていない状態で実行するとエラーが起きます。

    main-image 内の画像は querySelector で取得し、src を変更することで表示する画像を切り替えます。

    サムネイル画像は querySelectorAll で複数まとめて取得し、forEach で一つずつイベントを加えます。mouseover はマウスが乗った瞬間に発火するイベントで、e.target はそのサムネイルを指します。

    画像切り替え後、animate を使って opacity を 0 から 1 に変化させることでフェードアニメーションが動きます。Web Animations API を利用しているため CSS なしでアニメーションができます。


    WordPress での利用方法

    ・HTML はカスタム HTML ブロックに貼る
    ・CSS は追加 CSS または style タグで追加可能
    ・JavaScript は script タグで記事内に記述できる

    テーマに依存せず、他ページに干渉しないため安心して利用できます。


    まとめ

    このギャラリーでは次の JavaScript 基礎が学べます。

    ・DOM 取得(querySelector / querySelectorAll)
    ・イベント処理(addEventListener)
    ・event.target の扱い
    ・img.src による画像の差し替え
    ・Web Animations API(element.animate)

    実用的でありながら初心者が理解しやすい構造のため、練習に最適です。

  • スクロール時にふわっと左下右からフェードインさせる方法

    スクロール時にふわっと左下右からフェードインさせる方法

    スクロールして要素が画面に入ったときに、
    それぞれが 左・下・右 から柔らかくスライド&フェードインする動きを作ります。

    今回使うのは Intersection Observer(ブラウザ標準API)
    jQuery不要で、軽量・高速です。


    実装イメージ

    スクロールすると…

    • 左からスッと登場「WordPress」
    • 下からふわっと出てくる「CSS」
    • 右からスライドインする「JavaScript」

    という順番で自然にフェードインします。

    WordPressアイコン

    WordPress

    CSSアイコン

    CSS

    JSアイコン

    JavaScript


    HTML

    <section class="container">
      <div class="element1">
        <img src="./imgs/WordPressアイコン.png" alt="WordPressアイコン">
        <h3>WordPress</h3>
        <p>CMSシェアNo.1</p>
      </div>
    
      <div class="element2">
        <img src="./imgs/cssアイコン.png" alt="cssアイコン">
        <h3>CSS</h3>
        <p>好みのレイアウトに。</p>
      </div>
    
      <div class="element3">
        <img src="./imgs/jsアイコン.png" alt="jsアイコン">
        <h3>JavaScript</h3>
        <p>より豊かな表現を。</p>
      </div>
    </section>
    

    CSS

    /* コンテナ全体 */
    .container {
      display: flex;
      flex-wrap: nowrap;
      gap: 21px;
      justify-content: center;
      align-items: center;
    }
    .container img {
      width: 210px;
    }
    
    /* 各要素(共通) */
    .element1, .element2, .element3 {
      margin: 12px;
      padding: 20px;
      background-color: #fff;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      text-align: center;
      opacity: 0; /* 初期は非表示 */
      transition: all 0.6s ease-out;
    }
    
    /* 初期位置の設定 */
    .element1 {
      transform: translateX(-100%); /* 左から登場 */
    }
    .element2 {
      transform: translateY(100%);  /* 下から登場 */
    }
    .element3 {
      transform: translateX(100%);  /* 右から登場 */
    }
    

    JavaScript(Intersection Observer)

    document.addEventListener('DOMContentLoaded', function() {
      const options = {
        threshold: 0.1 // 要素の10%が見えた時に実行
      };
    
      const observer = new IntersectionObserver(function(entries, observer) {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            entry.target.style.opacity = '1';
            entry.target.style.transform = 'translate(0, 0)';
            observer.unobserve(entry.target); // 一度だけ実行
          }
        });
      }, options);
    
      document.querySelectorAll('.element1, .element2, .element3')
        .forEach(el => observer.observe(el));
    });
    

    解説:Intersection Observerとは?

    Intersection Observer は
    「要素が画面内に入った瞬間」を検知できるブラウザ標準APIです。

    アニメの基本的な流れは次の通りです。

    • 監視対象を登録:observer.observe(el)
    • 画面に入ると実行:entry.isIntersecting が true
    • opacity + transform で自然な動き
    • unobserve() で1度だけアニメーションを実行

    threshold の意味

    threshold: 0.1
    

    これは
    「要素の10%が見えた瞬間にアニメ開始」
    という意味です。

    値を大きくすると、よりしっかり見えた状態で発火します。


    応用アイデア

    応用例使い方
    .element4 を追加斜め上からフェードインなど
    transform: scale(0.8) → 1拡大しながら登場
    opacity のみシンプルフェード
    unobserve() を外す通るたびに毎回アニメ

    まとめ

    ポイント内容
    Intersection Observerスクロール検知が軽量&高速
    transform + opacityスライド × フェードが定番
    threshold登場のタイミングを調整
    unobserve()アニメを1回だけ実行

    スクロールに合わせて自然にふわっと動かしたいとき、
    最も軽量で扱いやすい実装方法です。

  • JavaScript の animate() で作る「拡大 → 回転 → 色変化」の連鎖アニメーション

    JavaScript の animate() で作る「拡大 → 回転 → 色変化」の連鎖アニメーション

    JavaScript の animate() メソッドを使えば、CSS を書かずに「拡大 → 回転 → 色変化」といった複数の動きを順番に実行できます。

    この記事では、クリックすると丸が
    「拡大 → 回転 → 色変化 → 元に戻る」
    という一連のアニメーションをする仕組みを解説します。


    完成イメージ

    クリックすると、丸がふわっと動いて色が変わります。


    ファイル構成

    js-lesson/
    ├── index.html
    ├── style.css
    └── script.js
    

    HTML

    <section>
      <h1>クリックで連鎖アニメーション</h1>
    
      <div class="circle"></div>
    
      <button id="anim-btn">動かす!</button>
    
      <script src="./script.js"></script>
    </section>
    

    CSS

    section {
      font-family: "Yu Gothic", sans-serif;
      background: #f7f8fa;
      text-align: center;
      margin-top: 5rem;
    }
    
    .circle {
      width: 100100px;
      height: 100px;
      background: #6c5ce7;
      border-radius: 50%;
      margin: 3rem auto;
    }
    
    button {
      padding: 0.6rem 1.2rem;
      background: #6c5ce7;
      color: #fff;
      border: none;
      border-radius: 8px;
      cursor: pointer;
      transition: opacity 0.3s ease;
    }
    button:hover {
      opacity: 0.8;
    }
    

    JavaScript

    const circle = document.querySelector(".circle");
    const button = document.querySelector("#anim-btn");
    
    button.addEventListener("click", async () => {
      // ① 拡大
      await circle.animate(
        [{ transform: "scale(1)" }, { transform: "scale(1.5)" }],
        { duration: 400, easing: "ease-out", fill: "forwards" }
      ).finished;
    
      // ② 回転
      await circle.animate(
        [{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }],
        { duration: 600, easing: "ease-in-out", fill: "forwards" }
      ).finished;
    
      // ③ 色変化
      await circle.animate(
        [{ background: "#6c5ce7" }, { background: "#ff7675" }],
        { duration: 500, fill: "forwards" }
      ).finished;
    
      // ④ 初期状態に戻す
      circle.animate(
        [
          { transform: "scale(1.5) rotate(360deg)", background: "#ff7675" },
          { transform: "scale(1) rotate(0deg)", background: "#6c5ce7" }
        ],
        { duration: 400, easing: "ease-out" }
      );
    });
    

    解説

    animate() は JavaScript だけでアニメーションを作れるメソッドです。

    element.animate(
      [{ opacity: 0 }, { opacity: 1 }],
      { duration: 1000 }
    );
    

    次に async / await について。

    • async:この関数の中で await を使える宣言
    • await:処理が終わるまで次へ進まない
    • .finished:アニメーション完了を Promise で返す

    つまり次の1行はこういう意味です。

    await circle.animate(...).finished;
    

    → 「このアニメが終わるまで待ってから次を実行」

    これで、拡大 → 回転 → 色変化 と順番に動かせます。


    まとめ

    • animate():JSだけでアニメーションを実行
    • async / await:アニメを順番に進める仕組み
    • .finished:アニメ終了を検知
    • fill: “forwards”:最後の状態を保持

    連鎖アニメーションを理解すると Web サイトに動きが出て、表現の幅が大きく広がります。