ポートフォリオの詳細表示をモーダル化してUXを改善する
ポートフォリオサイトの作品詳細を、ページ遷移なしで閲覧できるようにモーダルウィンドウ化しました。DOMParserを使ったHTML取得や、実装時のハマりポイントについて。
こんにちは!パン君です。
これまでこのサイトの「ポートフォリオ一覧」から作品をクリックすると詳細ページ(portfolio/xxxx.html)に遷移する仕様になっていました。
しかしポートフォリオを見に来てくれた人は「 いろいろな作品をザッピングしたい 」はずです。
「クリックして詳細へ移動」→「ブラウザバックで戻る」→「またスクロールして次の作品へ...」という操作は、地味ながらストレスになります。
そこで 一覧ページを維持したまま、詳細情報をモーダルウィンドウで重ねて表示する 形に改修しました。
実装の方針
このサイトはビルドツールを使ってMarkdownファイルから静的なHTMLファイルを生成しています。
ポートフォリオの詳細ページもすでに portfolio/work_01.html のような形で実ファイルとして存在しています。
JSONデータにすべての情報を詰め込んでJSで構築する方法もありますが、
「すでに生成されている詳細ページのHTMLを再利用する」 方が、SEO的にもビルドフロー的にも無駄がありません。
処理の流れ
- ユーザーがカードをクリック。
- JSで詳細ページのURL (
portfolio/xxxx.html) をfetchする。 - 取得したHTMLテキストをパースして、中身のコンテンツ部分だけを取り出す。
- モーダルの中にポイッと入れる。
技術的なポイント
1. HTMLをfetchしてパースする
fetch で取得できるのは単なる「文字列」です。これをDOM要素として扱うために DOMParser を使います。
// HTMLを取得
const res = await fetch(contentPath);
const text = await res.text();
// 文字列をHTMLドキュメントとしてパース
const parser = new DOMParser();
const doc = parser.parseFromString(text, "text/html");
// 必要な部分(.work-detail)だけを抜き出す
const detail = doc.querySelector(".work-detail");
// モーダルに挿入
modalContent.appendChild(detail);これで、iframe を使わずにシームレスにコンテンツを埋め込むことができます。
2. 相対パスの罠
詳細ページは portfolio/ ディレクトリ配下にある前提でビルドされているため、画像などのパスが ../assets/img/... のようになっています。
これをトップページ(ルート階層)のモーダルでそのまま表示すると、リンク切れになってしまいます。
そこで、取り出したDOMに対してパスの書き換え処理を行いました。
// "../" で始まるパスを修正する
function fixPaths(element) {
const nodes = element.querySelectorAll('[src], [href]');
nodes.forEach((node) => {
// 属性値を取得して "../" を削除するなど置換処理
// ...
});
}ハマったポイント:中身が表示されない?
実装していざ動かしてみるとモーダルは開くのに 中身が真っ白 という現象が発生しました。
開発者ツールで見ると要素は存在しているのに、画面には映っていません。
原因:スクロールアニメーション
原因は、詳細ページ側で使っていた「スクロールしたらふわっと表示する」ためのクラス reveal-on-scroll でした。
.reveal-on-scroll {
opacity: 0; /* 初期状態は透明 */
transform: translateY(20px);
/* スクロールして画面内に入ったら .is-visible が付いて不透明になる */
}詳細ページとして表示するときはスクロール検知スクリプトが動くので問題ないのですが、
モーダル内に挿入されたときはそのスクリプトが動かず、 永遠に opacity: 0 のまま待機 してしまっていたのです。
解決策
モーダルに挿入する前にこのクラスを削除するようにしました。
const detail = doc.querySelector(".work-detail");
// アニメーション用クラスを削除して強制表示
detail.classList.remove("reveal-on-scroll");これで無事に表示されるようになりました。
まとめ
今回の改修で作品の閲覧体験(UX)はかなり向上したと思います。
- ページ遷移がないのでサクサク見れる。
- 一覧のスクロール位置が維持されるので、続きから探しやすい。
- 詳細ページへの直接リンク(SEO)も維持されている。
「静的サイトだから」と諦めず、JavaScriptをうまく使うことで、動的サイトのようなリッチな挙動を実現できました。
コメントを読み込み中...