ブログ
BLOG
とあるページ内のボタンをクリックするとモーダルウインドウが開く。
これ自体はそんなに難しい技術ではなく、プラグインを使わずとも自力で実装できてしまえるかと思います。
しかし、『トップページ内にあるリンクから遷移するとそのサブページ内のモーダルが開かれた状態で表示される。』
そんな実装が必要になった機会がありました。
これはちょっとわからないな、プラグインを使うと尚更できないな・・・と思えるようなものでして、頑張って実装しました。
調べてみてもあまりヒットしないようなテーマだったこともあり、それだったらブログ内で紹介できればと思い今回テーマに挙げてみました。
早速見ていきましょう。
必要となるコードは以下にすべて記載しています。
※今回はモーダルそのものの実装に関する事はほぼ触れていません。
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年入社。東進ハイスクールの現代文講師林修先生を敬愛してやまないコーダー。林先生に負けないくらいの知的好奇心や探求心を武器にホームページ制作に役立つ有益な情報を発信する。好きな食べ物はいなりです。