アンカーリンクのズレ修正

SITE

 当ブログのWordPressではこれまであまりアンカーリンクを使っていなかったので気がつかなかったが、たくさんアンカーをつけてページ外からリンクしたら、アンカー設定箇所と違う箇所にジャンプしてしまうことに気づいた。

スポンサーリンク

ズレる

 アンカーリンクとはページ内の途中へのリンクで、
 例えば、ページ内の途中にid="●●●"

<a id="yachimata">八街</a>

とアンカー設定して、任意の場所から#●●●でリンクさせることができる。

<a href = "#yachimata">やっちまった</a>

 ページ外からのリンクならばURLの後に#●●●でリンク。

<a href = "https://www.mitsumatado.com/zen/anchor-zure/#yachimata">やっちまった</a>

 テスト。

 やっちまった

 |
 |
 |
 |
 |
 V

 八街

 PCでは問題ない。
 スマートフォンだとズレる。

 ネットで検索かけると
 ヘッダーを固定しているページ(position:fixed指定のページ)で、
 リンク先のアンカー設定箇所がヘッダーの下に隠れてしまう
というパターンが多いようだ。

 CSSかJavaScript(JS)でズラせば解消できる、とのこと。

 今回遭遇したズレはコレじゃない。
 アンカー設定箇所がジャンプ先の画面の下のほう、もしくはフッターより下の画面外にある。

スポンサーリンク

ズレ解消

 アンカーリンクを使っていないと思っていても見出し(H2、H3、H4、H5、H6)をつけて目次を使っていれば、自動的に
 #toc1、#toc2、#toc3、……
のアンカーが連番でふられている。
 例えば、上のH2見出し「ズレ解消」のアンカーリンクは、

https://www.mitsumatado.com/zen/anchor-zure/#toc2

 ページ内の目次からのリンクは正しい位置にジャンプする。
 同じURLなのにページ外からのリンクだとズレる。

 アンカー設定が間違っているわけではない。

 どうやらページを読み込み終える前に計算されたアンカー設定箇所の位置と
 ページを読み込み終えた後に計算されるアンカー設定箇所の位置が
合っていないようだ。

 でも画像の遅延読み込み LAZY LOADは使っていないし……。

 アンカーリンクの数が40~50あるページで、
 上のほうのリンクはたいしたズレではなく(だから気づかなかった)、
 下のアンカーリンクほど下方にズレて、しまいに画面外になってしまう。
 見出しの高さが関係しているのだろうか。
 ズレすぎちゃって困る。

 調整しようにもPCではズレていない。

 ブラウザ(Safari)の問題かもしれないので、
 修正を諦めかけたが、
 やっぱり修正してやった

 参考ページは、

WEBDESIGNDAY INSPIRATION 【jQuery】ページ内リンクをページ外からでもスムーズにスクロールさせる(webdesignday.jp/inspiration/technique/jquery-js/4022/

 ダイレクトではなくいったんスクロールをトップにして、
 ページを読み込み終えるのを待ってから、
 アンカー設定箇所へジャンプさせる。
 これでページ内の目次からのリンクとほぼ同じ振舞いになる。

 当ブログのWordPressではこれまでJavaScriptを使っていなかったが、
 ひとまず全ページ適用ではなく
 個別ページでの利用ということで
 「カスタムHTML」というブロックに以下のコードを記入した。  

<script>
jQuery(window).on('load', function(){
	var headerHeight = $('.site-header').outerHeight();
	var urlHash = location.hash;
	if(urlHash){
	$('html,body').stop().scrollTop(0);
	setTimeout(function(){
	var position = $(urlHash).offset().top - headerHeight;
	$('html,body').animate({scrollTop: position},'slow');
	},100);
	}
});
</script>

 JavaScriptで当たり前のように使われているjQueryライブラリはWordPressに最初から入っているが、WordPressでは
 $(function(){ });
ではなく
 jQuery(function(){ });
で囲む必要がある。

 今回は、
 jQuery(function(){ });
ではなく
 jQuery(window).on('load', function(){ });
で囲んである。

 3行目の
 location.hash
で、アンカーリンク(URLの#の後)を取得。

 $(urlHash).offset().top
がアンカー設定箇所の位置取得。

 setTimeout(function(){  },100);
の部分は、100ms(0.1秒)後にスクロール。(ブラウザが)ページを読み込み終えてからスクロール。

 2行目はヘッダーの高さ取得。アンカー設定箇所がヘッダーの下に隠れてしまう場合の対処。念のため。

スポンサーリンク
ふシゼン
タイトルとURLをコピーしました