jqueryのスクロールでページ内リンクに推移させると位置がずれる問題の解決策
はてなブログの目次をjqueryで作って目次のリンクをクリックしたら、見出しの位置までスクロールさせる実装をさせていたのですが、なぜか見出しの中心までスクロールしてしまうので対策を考えました。
今回はjqueryでスクロールさせる場合ですね。
目次をクリックしたらその見出しまでスクロールさせるコード
$('.section-list a').on("click", function() { const target = $(this.hash); // 対応するセクションの要素を取得する const headerHeight = target.outerHeight() / 2; // セクションの高さの半分を取得する const topOffset = target.offset().top; // セクションの上端からの距離を取得する const scrollTo = topOffset - headerHeight; // スクロール位置を微調整する $('html,body').animate({ scrollTop: scrollTo }, 50); return false; });
コードレビュー
jqueryのoffset().topは指定された要素のドキュメント上の位置を返します。具体的には、指定された要素の上端が、ドキュメント上のどの位置にあるかを返すものですが、なぜか中心までスクロールしてしまいます。この原因はわからなかったのですが、見出し要素の中心までスクロールしてしまうのでこれを修正するために「見出しの高さ÷2」分を差し引くことで解決しました。
const headerHeight = target.outerHeight() / 2; ←これで見出しの高さ÷2 分の高さを取得 const scrollTo = topOffset - headerHeight; ← トップオフセットからさきほどのheaderHeightを引きます
$(this.hash)について
$(this.hash)はリンク先の要素を取得します。
たとえば
<h2 id="hoge">見出し</h2>
となっている場合はa要素は
<a href="#hoge">リンク</a>
の形になっている必要があります。
hashとは#です。#hogeハッシュの要素を取得するということですね。