offset().topで位置がずれる件について
ページ内リンクがたくさんある長いページで下のアンカーリンクになるにつれどんどん飛び先がずれて「なんでだ!?」と思い色々調べたので備忘録
原因
.offset().top
を使って上からの距離を取得してスムーズスクロールしながらリンク先まで移動する記述をしていたので、console.log
を使って距離を確認したところ、どうにも画像の高さ分を取得できていないのが原因だった。
1度スクロールして画像が表示をされていることを確認してからアンカーリンクを押したら画像の高さを認識して飛ぶのが確認できた。
そもそも.offset().topってなによ?
ドキュメントの左上を起点に距離を取得するメソッドらしい。
実際の使い方と実際に使ったコードは以下
// ヘッダーメニューがついてくる場合高さを変数に入れとく
var hsize = $('#header').height();
$('a[href^="#"]').on('click', function(){
// クリックした要素を変数に入れる
var Target = $(this.hash);
// ドキュメント上部よりリンク先までの距離を取得
var TargetOffset = $(Target).offset().top;
var Time = 500;
// スムーズスクロールしながらリンク先まで移動
$('html, body').animate({
scrollTop: TargetOffset - hsize - 20
}, Time);
return false;
});
scrollTop: TargetOffset - hsize - 20
は固定ヘッダー分の高さをリンク先までの距離から引いて、それだけだとヘッダーとリンク先がくっつくので「20px」分離すようにしています。
以下が参考になりました
▼jQueryのoffset() で表示位置の取得と要素の移動
https://www.flatflag.nir87.com/offset-1167
対策:画像の読み込みを遅らせる
画像分の高さが取得できていない事がわかっていたので、画像の読み込みを遅延させる記述を試したのでメモがてら記述します。
$(window).load(function() {
// 画像とか読み込み終わったら実行させるコード
}
参考にしたサイト
▼【jQuery】処理実行タイミング $(document).readyと$(window).load
https://qiita.com/katsunory/items/3ba4683629333b94b2be
プラグインが原因だった
結果的に「BJ Lazy Load」というファーストビュー以外はスクロールしたら読み込むプラグインを入れてて、設定の「Lazy load images」の部分をオフにしたら解決しました。
ページごとにプラグインを有効・無効にするには各ページに「BJ Lazy Load」の設定項目「Skip lazy loading for this page」がでるのでチェックすればそのページのみプラグインは適応されない。
scrollTop()
というのがあるがこっちは指定した要素のスクロールバーの位置を取得できる