アンカーリンクで何がなんでもページトップを表示させたい!

アンカーリンクで何がなんでもページトップを表示させたい!

別ページのアンカーリンクを踏んだ際に、アンカーではなくページトップへ遷移させるにはどのような方法が最適かを検証してみました。

なぜそんなことを始めたかというと、別ページに遷移した後一番上から綺麗にスクロールさせたいというのがきっかけです。

ブラウザによっては動作しなかったり、アンカーの位置やページの重さなども考慮しないといけなかったため、おそらく1000回以上は読み込みを繰り返し行ったんじゃないでしょうか…笑

今回の検証には、JavaScriptを利用し、アンカーリンクでページ遷移したときの挙動に焦点を当てています。

目次

即座にジャンプ

window.scrollTo(0, 0);
Chrome・Edge
  • アンカーへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(ちらつきあり)
Safari
  • アンカーへ飛ぶ
Firefox
  • ページトップへ飛ぶ(ちらつく時がある)
  • リロードするとページトップへ飛ぶ

遅延実行でジャンプ

setTimeout(function () {
  window.scrollTo(0, 0);
}, 0);
Chrome・Edge
  • アンカーへ飛ぶ(ちらつきあり)
  • 稀にページトップへ飛ぶ
  • リロードすると現在地で更新される(ちらつきあり)
Safari
  • アンカーへ飛ぶ
Firefox
  • ページトップへ飛ぶ(ちらつく時がある)
  • リロードするとページトップへ飛ぶ
setTimeout(function () {
  window.scrollTo(0, 0);
}, 20);
Chrome・Edge
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(ちらつきあり)
Safari
  • ページトップへ飛ぶ
  • たまにアンカーへ飛ぶ
  • リロードも同様
Firefox
  • ページトップへ飛ぶ(ちらつく時がある)
  • リロードするとページトップへ飛ぶ
setTimeout(function () {
  window.scrollTo(0, 0);
}, 100);
Chrome・Edge
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(ちらつきあり)
Safari
  • ページトップへ飛ぶ(ちらつく時がある)
  • リロードも同様
Firefox
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードするとページトップへ飛ぶ

DOMツリー構築後にジャンプ

document.addEventListener("DOMContentLoaded", function () {
  window.scrollTo(0, 0);
});
Chrome・Edge
  • アンカーへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(ちらつきあり)
Safari
  • アンカーへ飛ぶ
Firefox
  • ページトップへ飛ぶ(ちらつく時がある)
  • リロードするとページトップへ飛ぶ

即座にジャンプさせた場合と同様でした。

ページが完全に読み込まれた後にジャンプ

window.addEventListener("load", function() {
  window.scrollTo(0, 0);
});
Chrome
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(稀にちらつく時がある)
Edge
  • Chromeと同じ
  • リロードすると現在地で更新される
Safari
  • アンカーへ飛ぶ
Firefox
  • ページトップへ飛ぶ(ロード中はアンカーが表示される)
  • リロードするとページトップへ飛ぶ

DOMツリー構築後&遅延実行後にジャンプ

document.addEventListener("DOMContentLoaded", function () {
  setTimeout(function () {
    window.scrollTo(0, 0);
  }, 0);
});
Chrome
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードすると現在地で更新される(ちらつきあり)
Edge
  • Chromeと同じ
Safari
  • ページトップへ飛ぶ
  • アンカー先によってはアンカーへ飛ぶ
  • リロードも同様
Firefox
  • ページトップへ飛ぶ(ちらつきあり)
  • リロードも同様

休憩

ここまでで分かったのは、どのタイミングでも「ページトップ→アンカー位置→ページトップ」というように瞬間的に移動して画面がちらつく事があり、ブラウザの挙動が揃わず安定しないということです。

つまりこのアプローチだけでは対処できません。

では改めて、ページトップへ飛ぶときはどんな時か。

アンカーリンクではない時、もしくはジャンプ先のアンカーがない時です。

ジャンプ先のアンカー、すなわち”ID”を取り除く方法は、CSSやJSで制御していることが多く、無くなると厄介なので却下です。

消去法で、URLからハッシュを取り除く方法。
即座に実行されれば、強制的にページトップへ行くかもしれません。

新しいページが読み込まれると、初期表示の段階でアンカー位置を考慮せず、一旦ページトップが表示されるためです。DOMツリーの解析が完了すると、指定されたアンカー位置に一瞬でジャンプするので、それまでにハッシュを取り除けば良いということになります。

では検証してみます。

ページ遷移時にURLからハッシュを取り除く

const urlHash = window.location.hash;
if (urlHash) {
  // ハッシュを取り除く
  history.replaceState(null, '', window.location.pathname);

  setTimeout(function () {
    // ハッシュを再設定
    history.replaceState(null, '', window.location.pathname + urlHash);
  }, 100);
}
Chrome
  • ページトップへ飛ぶ
  • リロードすると現在地点で更新される
Edge
  • ページトップへ飛ぶ
  • リロードすると現在地で更新される(稀にページトップがちらつく)
Safari
  • ページトップへ飛ぶ
  • リロードすると現在地で更新される(稀にページトップへ飛ぶ)
Firefox
  • アンカーへ飛ぶ
  • リロードも同様

Firefox以外は、綺麗にページトップが表示されるという結果になりました!

Firefoxはアンカーが含まれると、瞬時にアンカーへ飛ぶ仕様のようです。

考察

リロード時の挙動が少し気になったので、コードを全て消して検証を行います。

ハッシュのないURLをリロードした時

  • Chrome:現在地で更新される
  • Edge:現在地で更新される(稀にページトップがちらつく)
  • Safari:現在地で更新される(稀にページトップへ飛ぶ)
  • Firefox:現在地で更新される

稀にページトップが見えるのはブラウザの仕様のようですので、コードによる不具合ではないことが判明しました。

ハッシュ付きのURLをリロードした時

  • Chrome:現在地で更新される
  • Edge:現在地で更新される
  • Safari:アンカーへ飛ぶ
  • Firefox:現在地で更新される

なんとSafari以外はアンカーへ飛びませんでした。

ということは、リロードした時には、無理にページトップからアンカーへスクロールさせなくても問題はないと捉えることもできます。

リロードの挙動はブラウザに委ねることにし、ページ遷移した際にページトップへ飛ぶかどうかに重点をおきたいと思います。

完成しました

const urlHash = window.location.hash;
if (urlHash) {
  // ハッシュを取り除く
  history.replaceState(null, '', window.location.pathname);
  // ページトップへジャンプ
  window.scrollTo(0, 0);

  setTimeout(function () {
    // ハッシュを再設定
    history.replaceState(null, '', window.location.pathname + urlHash);
  }, 100);
}

Firefoxにも対応させるため、ページトップへジャンプさせるコードも追加し、無事主要ブラウザ全てでページトップへ遷移させることができました。

ジャンプさせた際には瞬間的なチラつきが見える場合もありますが、総合的に見て妥協できるラインだと考えています。

ハッシュを再設定は、お好みでどうぞ。

おすすめWEBスクール

WEB制作やWEBデザインを学びたいなら、SNSでも話題の「デイトラ」がおすすめ!
どのコースも10万円前後と業界最安値で、副業や転職に向けて十分なスキルを身につけることができます。

役に立ったら他の方にシェア

お気軽にコメントどうぞ

コメントする

目次