コンテンツへスキップ

固定ヘッダー設置サイトでページ内外アンカーリンクを上手くコントロールする

ページ内外アンカーリンク施策

固定ヘッダーを有するサイトで別ページへのアンカーリンクを上手く機能させるには手がかかりますよね。ページ内外のアンカーリンクをヘッダーの高さ分調整しつつ正確に作動させる、Javascriptによる施策をご紹介します。

当サイトでは、固定ヘッダーを採用しています。テーマには元々その機能は付いていませんでしたので、position: fixed;でレスポンシブ対応の固定ヘッダーを設置しました。

当初、別ページへのアンカーリンクはさほど多くなかったので、とりあえずCSSで処理していたのですが、徐々に他ページへのアンカーリンクが増えてきましたので、Javascriptの書き換えと追記を実施しました。

ページ内アンカーリンクの場合

当サイトのページ内アンカーリンクは以下のようにしました。

jQuery(function () {
      var headH = jQuery("header").outerHeight(); 
      var animeSpeed = 800; 
      jQuery("a[href^='#']").on({
          "click": function () {
              var href = jQuery(this).attr("href");
              var target = jQuery(href == "#" || href === "" ? "html" : href);
              var position;
              position = target.offset().top - headH; //
              jQuery("body,html").stop().animate({
                  scrollTop: position
              }, animeSpeed);
              return false;
          }
      });
  });

2行目
jQuery(“header”).outerHeight();で、
固定ヘッダーの高さを取得し、
headHに入れる。

3行目
スクロールアニメーションのスピードです。

4,5行目
アンカーリンクをクリックしたら・・・

9行目
ページトップからターゲットまでの距離から、
ヘッダーの高さを引いてスクロールさせます。

ページ外アンカーリンクの場合

他ページへのアンカーリンクの場合、上述のコードではテキストが固定ヘッダーの裏側に隠れてしまいます。それで、ページ外アンカーリンクのため、以下のコードも書き加えました。

jQuery(function () {
      var headH = jQuery("header").outerHeight();
      var animeSpeed = 800;
      var urlHash = location.hash;
      if (urlHash) { 
          jQuery("body,html").scrollTop(0);
          setTimeout(function () { 
              var target = jQuery(urlHash);
              var position = target.offset().top - headH;
              jQuery("body,html").stop().animate({
                  scrollTop: position
              }, animeSpeed);
          }, 0);
      }
  });

4行目
var urlHash = location.hash;
別ページに移動したら、URL付随のハッシュタグを取得する。

5、6行目
該当ハッシュタグがあればスクロール処理に移行するが・・・

7~13行目
処理を分割してハッシュタグ関連の処理を確実化するため、引数0の SetTimeout で挟みました。当サイトにとっては効果覿面でした。

施策の結果と
今後の課題

施策後、アンカーリンクはページ内外共に同じ動作を経て正確な位置に移動するようになりました。

今回、以前の投稿記事 トップへ戻るボタンと目次をプラグインなしで実装(別タブで開きます。)でご紹介した方法とは異なるコードを採用しましたが、ページ内リンク、ページ外リンク共に同じ動作を経ての移動に満足しています。

只、今回は二つの課題点が残りました。

  1. ページ内リンクとページ外リンク其々のため2つのコードを作成しましたので、折を見て一つに纏めたいと考えています。手短に。
  2. jQuery(“body,html”)…で、callback関数が2回呼ばれるのもあまり気持ちよくありませんので、改善します。

ところで、今回の施策後、PageSpeedInsightsで計測してみましたが、予想以上の数値が出ました。下図のとおりです。JSファイルを定期的に見直し、都度ブラッシュアップするよう心掛けていますが、条件が整えばそれなりの結果は出せているようです。

と言っても私が使っているのはロリポップのライトプランというチープなものですので、数値は参考程度に考えていますが。

ページスピードインサイト携帯電話20230302
ページスピードインサイトPC20230302
to page top