当ブログの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行目はヘッダーの高さ取得。アンカー設定箇所がヘッダーの下に隠れてしまう場合の対処。念のため。