固定ヘッダー対応!jQueryベースのアンカーリンク平滑スクロール+位置補正実装

はじめに
「アンカーリンクをクリックすると、スクロール先の見出しがヘッダーに隠れてしまう」
そんな経験はありませんか?特に固定ヘッダーを導入したウェブサイトでは、ページ内リンクとスクロールの整合性に悩まされることが少なくありません。
今回は、jQuery を用いたスムーズスクロールと動的な位置補正機能を組み合わせたコードを紹介します。ページ読み込み時・ハッシュ変更時・DOM準備完了時のいずれにも対応し、ユーザー体験(UX)を損なうことなくページ内遷移を実現できます。
実装コード
function smoothScrollToHash() {
const hash = window.location.hash;
if (!hash) return;
const targetId = hash.substring(1); // #を除去
const $target = $(`.${targetId}`);
if (!$target.length) return;
const headerHeight = $(".home .site-header").height();
const targetPosition = $target.offset().top - headerHeight;
// スムーズスクロール+位置補正機能
$("html, body").stop().animate({
scrollTop: targetPosition
}, 1000, () => {
setTimeout(() => {
// 500ms後に位置を再計算(動的コンテンツ対応)
const correctedPosition = $target.offset().top - headerHeight;
$("html, body").animate({
scrollTop: correctedPosition
}, 500);
}, 500);
});
}
// ページ読み込み時・ハッシュ変更時に発動
$(window).on("load hashchange", smoothScrollToHash);
// DOM準備完了時も実行(ページ内アンカー用)
$(document).ready(smoothScrollToHash);
機能解説
✅ スムーズスクロール
ページ内リンク(例:#section1)が URL に存在する場合、対象要素まで滑らかにスクロール。
✅ 固定ヘッダー対応
.site-header の高さを自動取得し、見出しが隠れないように位置補正。
✅ 動的な再補正
一度目のスクロール後、500msのディレイを設けて再度位置を再計算。これにより、非同期読み込みされた画像やセクションのズレにも対応。
✅ トリガーイベントの網羅
- $(document).ready():通常のページ読み込み時
- $(window).on(“load”):画像などのリソース読込後
- $(window).on(“hashchange”):ハッシュ変更時(SPA対応)
使用シナリオ
このコードは以下のようなシーンで特に有効です:
- 固定ヘッダーを導入したシングルページアプリケーション(SPA)
- 目次ナビゲーションのある長尺ページ
- 画像やセクションを後から読み込む非同期コンテンツ
- スクロール先がズレて表示される UI 問題の回避
応用と改善のヒント
IDとclass両方に対応したセレクターを使うことで、柔軟性を高められます:
const $target = $(`#${targetId}, .${targetId}`);
ページ内リンククリックにもスムーズスクロールを適用するには以下を追加:
$("a[href^='#']").on("click", function (e) { e.preventDefault(); const hash = this.hash; if (!hash) return; history.pushState(null, null, hash); smoothScrollToHash(); });
まとめ
アンカーリンクによるページ内遷移は UX に直結する要素です。今回紹介した実装は、デザインの美しさと機能の実用性を両立させるための基本テクニックの一つと言えるでしょう。
固定ヘッダーや非同期読み込みなど、現代の Web 開発において発生しやすい問題にも配慮されたコードですので、ぜひ貴社のサイトやプロジェクトに取り入れてみてください。