ヘッダー固定でページ内リンクをページ遷移で指定した時のズレを解消するJavaScript

ヘッダー固定にしていると頻発する問題として、「ページ内リンク先の位置がズレる!」があると思います。ズレるというか、ほとんどの場合は固定したヘッダーに隠れますね。

同じページ内でのページ内リンクだったらズレの解消も簡単だったりしますが、違うページに遷移した時のズレの解消がまあ面倒くさい。気づかなかったフリしてしれっと提出しようと何回思ったことか・・・笑

自分の中での暫定的に決まっている1つの書き方を紹介します。同じような問題に直面している方は参考にしていただければと思います!

はにわまん
コーディングしているとこういう細かい対応に意外と時間がかかったりします...泣

ページ遷移時のページ内リンクでズレを解消する

ザックリ処理を説明すると、ページ読み込みが終わったらURLの#hogeを取得して、ヘッダー分の高さだけ移動(アニメーション)するという動きになります。

/* ページ内リンク(別ページ) */
jQuery( window ).on( 'load', function() {
	id    = location.hash;
	speed = 0;
	headerHight = 128; // 固定ヘッダーの高さ
	if ( '' != id ) {
		pos = jQuery( id ).offset().top - headerHight;
		jQuery( 'html' ).animate({ scrollTop: pos }, speed );
	}
});

それぞれの処理は以下のような動きをしています。

  • jQuery( window ).on( ‘load’ ) → ページの読み込みが終ったら
  • location.hash; → URLの#hogeの値を取得
  • speed → 移動のスピードを指定(ページ遷移時は0でいいかと)
  • headerHight → 固定ヘッダーの高さを指定

headerHightの高さは、固定値ではなくjQuery( '#header' ).height();など固定ヘッダーの要素から高さを動的に取得した方がスマートかもしれません。

各種の値を取得したら、if文の中で高さの調整をしています。スクロールを制御しているのは<html>要素らしくanimateさせる要素はhtmlにしないと上手く動かないので注意してください。

これを実装すると動きとしては以下のようになります。

読み込みが終わってからの処理になるので、調整のための「ズズズッ」って動きが見えるのがちょっと気になりますね…

ここを改善する方法がネット上にはないので自分なりの暫定的な方法ですが、真っ白なローディング画面を入れて非表示にすることで対応したりしています。

ローディグ画面を加える

ローディング画面の実装方法はこの記事は詳しく解説しませんので、下記の記事を参考にしていただければと思います。

ページ読み込み中のローディング画面を表示するJavaScript

処理の流れとしては単純でして、先程のズズズって動く処理が終わるまで画面を真っ白にしてわたしたちに裏の処理を見せないという感じです。そして処理が終わったタイミングで覆っていた真っ白の画面を消しています。

動きとしては、以下のようになります(最初の動きと見比べていただければと思います)

HTML、CSS、JavaScriptにそれぞれ追加しましょう。HTMLとCSSは基本的にどこに追加してもOKです。

<div id="loader-bg"></div>
#loader-bg {
	background: #fff;
	height: 100%;
	left: 0;
	position: fixed;
	top: 0;
	width: 100%;
	z-index: 15;
}
/* ページ内リンク(別ページ) */
jQuery( window ).on( 'load', function() {
	id    = location.hash;
	speed = 0;
	headerHight = 128 // 固定ヘッダーの高さ
	if ( '' != id ) {
		pos = jQuery( id ).offset().top - headerHight;
		jQuery( 'html' ).animate({ scrollTop: pos }, speed );
	}
	jQuery( '#loader-bg' ).hide();
});

処理を見せずに画面全体を覆うためのHTML(#loader-bg)とCSSを用意して、ページの読み込みが終わるまで表示させます。JavaScriptでanimationのズズズの後にjQuery( '#loader-bg' ).hide();を追加して、ページ内リンクのポジションの調整が終わってから、画面を覆っていた#loader-bgを消すという流れです。

固定ヘッダーは常に表示

固定ヘッダーと画面全体を覆う#loader-bgは、重なりの順番を指定できます。個人的には全く真っ白の状態だと不安になるユーザーも多いと思うので、固定ヘッダーは常に表示させていてもいいかと思います。

重なりを制御しているのはz-indexのプロパティです。

#header {
	z-index: 40;
}
#loader-bg {
	z-index: 15;
}

上記のようにしておくと、#header部分は、#loader-bgより上に表示されるようになります。

おわり


ヘッダー固定でページ内リンクをページ遷移で指定した時のズレを解消するJavaScriptの紹介でした。こういう地味なところが意外と時間かかったりするので、コーディングは筋縄ではいかないなぁって感じですね…

この記事のソースで分からないところがあれば、console.log();などで値を確認しながら使うとより理解も深まるかもしれません。ページ内リンクのズレでお困りの方は参考にしていただければ嬉しいです。

このページが役に立ったら
いいね!お願いします

運営の励みになります...。

関連の記事