ブログ
BLOG

           

別ページからアクセスしてモーダルが開いた状態で表示するためのHTML,JavaScriptの記述に挑戦

良かったらハートを押してね!
+5

とあるページ内のボタンをクリックするとモーダルウインドウが開く。

これ自体はそんなに難しい技術ではなく、プラグインを使わずとも自力で実装できてしまえるかと思います。

しかし、『トップページ内にあるリンクから遷移するとそのサブページ内のモーダルが開かれた状態で表示される。』

そんな実装が必要になった機会がありました。

これはちょっとわからないな、プラグインを使うと尚更できないな・・・と思えるようなものでして、頑張って実装しました。

調べてみてもあまりヒットしないようなテーマだったこともあり、それだったらブログ内で紹介できればと思い今回テーマに挙げてみました。

早速見ていきましょう。

必要となるコードは以下にすべて記載しています。

※今回はモーダルそのものの実装に関する事はほぼ触れていません。

HTML

■リンク元ページのHTML

<!-- リンク元ページの内容 -->
<a href="./content/?from=1" class="item-1">
  <div class="photo">
    <img src="./img/item01.png" alt="項目1" />
  </div>
  <div class="info">
    <h3>タイトル1</h3>
    <p>説明文1</p>
  </div>
</a>

<a href="./content/?from=2" class="item-2">
  <div class="photo">
    <img src="./img/item02.png" alt="項目2" />
  </div>
  <div class="info">
    <h3>タイトル2</h3>
    <p>説明文2</p>
  </div>
</a>

<a href="./content/?from=3" class="item-3">
  <div class="photo">
    <img src="./img/item03.png" alt="項目3" />
  </div>
  <div class="info">
    <h3>タイトル3</h3>
    <p>説明文3</p>
  </div>
</a>

これら3つのリンクのどれかをクリックしたら、モーダルが開いた状態のページに飛びます。

ポイントはリンクのURLですね。

hrefの中身のcontentがサブページのディレクトリを指し、?from=1などがURLパラメータを指しています。このパラメータを指定することでモーダルが開かれるわけですね。


このリンクをクリックすると、ユーザーはcontentのページに移動しますが、それと同時に「from=1」という情報も一緒に送られます。リンク先のページのJavaScriptは、このパラメータを検出して「1番目のモーダルを表示する」と判断します。

■リンク先ページのHTML

<!-- モーダル1 -->
<div id="modal1" style="display: none" class="modal">
  <div class="container">
    <div class="modal-content">
      <div class="left">
        <img src="../img/content/detail01.jpg" alt="詳細画像1" />
      </div>
      <div class="right">
        <div class="profile">
          <p class="name">
            <span>タイトル1</span>の詳細
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目1
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目2
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
      </div>
    </div>
    <div class="modal-close">
      <button class="close-btn">×</button>
    </div>
  </div>
</div>

<!-- モーダル2 -->
<div id="modal2" style="display: none" class="modal">
  <div class="container">
    <div class="modal-content">
      <div class="left">
        <img src="../img/content/detail02.jpg" alt="詳細画像2" />
      </div>
      <div class="right">
        <div class="profile">
          <p class="name">
            <span>タイトル2</span>の詳細
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目1
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目2
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
      </div>
    </div>
    <div class="modal-close">
      <button class="close-btn">×</button>
    </div>
  </div>
</div>

<!-- モーダル3 -->
<div id="modal3" style="display: none" class="modal">
  <div class="container">
    <div class="modal-content">
      <div class="left">
        <img src="../img/content/detail03.jpg" alt="詳細画像3" />
      </div>
      <div class="right">
        <div class="profile">
          <p class="name">
            <span>タイトル3</span>の詳細
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目1
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
        <div class="message-box">
          <h4 class="title">
            項目2
          </h4>
          <p>
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。<br />
            ここにテキストが入ります。ここにテキストが入ります。
          </p>
        </div>
      </div>
    </div>
    <div class="modal-close">
      <button class="close-btn">×</button>
    </div>
  </div>
</div>

リンク先のモーダルがあるページのコードです。

ポイントはid名の指定ですね。こちらがJavascriptがこれがモーダルなんだと特定するための識別子になります。


例えば、一番上のid="modal1"ならば、リンク元の?from=1と連動していて、Javascriptがmodal1という要素を探して表示するために使われます。

また、モーダルは初期状態では当然非表示でないといけないのでstyle="display: none"を指定してます。本来CSSの方に書く方が綺麗なんでしょうが、今回はHTML側に書かせていただいています。

JavaScript

document.addEventListener("DOMContentLoaded", function () {
  const params = new URLSearchParams(window.location.search);

  if (params.has("from")) {
    const fromValue = params.get("from");
    const modalId = `modal${fromValue}`;
    
    showModal(modalId);
    
    const newURL = window.location.pathname;
    window.history.replaceState({}, document.title, newURL);
  }

  for (let i = 1; i <= 3; i++) {
    document.querySelectorAll(`.item-${i}`).forEach(function (element) {
      element.addEventListener("click", function (event) {
        event.preventDefault();
        showModal(`modal${i}`);
      });
    });
  }

  document.querySelectorAll(".close-btn").forEach(function (button) {
    button.addEventListener("click", function () {
      const modal = button.closest(".modal");
      hideModal(modal);
    });
  });

  function showModal(modalId) {
    const modal = document.getElementById(modalId);
    
    if (modal) {
      modal.style.display = "flex";
      document.body.style.overflow = "hidden";
    }
  }

  function hideModal(modal) {
    if (modal) {
      modal.style.display = "none";
      document.body.style.overflow = "auto";
    }
  }
});

さて、こちらが要となるJavaScriptの記述ですね。

じっくりと見ていきましょう。

コードを細かく解説していきます。

document.addEventListener("DOMContentLoaded", function () {
  // URLのクエリパラメータ(?以降の部分)を解析して取得
  const params = new URLSearchParams(window.location.search);

URLSearchParamsを使うことでモーダルがあるページが読み込まれたタイミングで、URLの中に含まれる?from=1のようなパラメータを探して取得します。

  // もしURLに「from」パラメータがあるならば(例:?from=1)
  if (params.has("from")) {
    // fromの値を取得(例:「1」)
    const fromValue = params.get("from");
    // その値を使ってモーダルIDを作る(例:「modal1」)
    const modalId = `modal${fromValue}`;
    
    // 対応するモーダルを表示
    showModal(modalId);

もしURL内にfromのパラメータがあったならば、その値を用いてIDを作ります。


?from=1を例に挙げるならば、modal${fromValue}の部分でmodal+1として、modal1というIDを作成します。そんな要領です。

showModal(modalId);に関しては後々に説明します。

    // URLからパラメータを削除(ページ更新時にモーダルが再表示されないようにする)
    const newURL = window.location.pathname;
    window.history.replaceState({}, document.title, newURL);
  }

一行目でパラメータ部分を削除してパスまでのURLを取得します。

なので、今回で言えば/content/までということになりますね。

2行目の記述で現在のURLからパスまでのURLに置き換える処理をしています。

これによりユーザーがページを更新した時にモーダルが再度開かれるのを防ぎます。

// 各アイテム(item-1〜item-3)にクリックイベントを設定
  for (let i = 1; i <= 3; i++) {
    document.querySelectorAll(`.item-${i}`).forEach(function (element) {
      element.addEventListener("click", function (event) {
        // リンクのデフォルト動作をやめる
        event.preventDefault();
        // クリックされたアイテムに対応するモーダルを表示
        showModal(`modal${i}`);
      });
    });
  }

リンク元のクラスitem-1~3に関する記述です。

本来aタグをクリックすると指定先のページに飛ぶかと思いますが、それをやめてモーダルが開かれるようにします。

// モーダルの閉じるボタンにクリックイベントを設定
  document.querySelectorAll(".close-btn").forEach(function (button) {
    button.addEventListener("click", function () {
      // クリックされたボタンが含まれるモーダルを特定
      const modal = button.closest(".modal");
      // そのモーダルを閉じる
      hideModal(modal);
    });
  });

close-btnクラスを持つボタンをクリックするとそのモーダルを閉じる、という記述です。

// モーダルを表示する関数
  function showModal(modalId) {
    // 指定されたIDのモーダル要素を取得
    const modal = document.getElementById(modalId);
    
    if (modal) {
      // モーダルを表示
      modal.style.display = "flex";
      // 背景スクロールを無効化
      document.body.style.overflow = "hidden";
    }
  }

  // モーダルを閉じる関数
  function hideModal(modal) {
    if (modal) {
      // モーダルを非表示
      modal.style.display = "none";
      // 背景スクロールを再有効化
      document.body.style.overflow = "auto";
    }
  }

前述したshowModal(modalId)とhideModal(modal)に関する記述です。

簡潔に言えばmodalクラスを持つモーダルの表示・非表示の制御です。


showModalはmodalクラスを表示(display: flex;)して、モーダルの背景の部分、つまりそのページの部分をスクロールできないようにしています。


hideModalはmodalクラスを非表示(display: none;)にして、背景部分を再びスクロールをできるようにしています。

これで以上となります。

ここまでの記述を用いれば、今回のテーマである『別ページからアクセスしてモーダルが開かれた状態で表示される』を実装することができます。

良かったら使ってみてください。

結構骨の折れる作業でしたが、新しい学びがあったり、実装できたときの達成感は大きかったです!

これらのコードを使った応用ができるかも!と思えたりもしました。

この調子でこれからもどんどん学んでいきたいですね。

愛知県内から名古屋市を中心にホームページ制作を行っている会社
株式会社 WWG(ダブルダブルジー)
愛知県 名古屋市中村区名駅5-16-17 花車ビル南館5F

TEL: 052-890-7007
※ ホームページ制作や活用サポートのお問い合わせはコチラから

プロフィール写真

いなり

コーダー

2022年入社。東進ハイスクールの現代文講師林修先生を敬愛してやまないコーダー。林先生に負けないくらいの知的好奇心や探求心を武器にホームページ制作に役立つ有益な情報を発信する。好きな食べ物はいなりです。

良かったらハートを押してね!
+5

おすすめの記事

CONTACT

お問い合わせ

ご不明な点やご質問等、
まずはお気軽にお問い合わせください。