1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ページ内リンクが固定ヘッダーに被るのをJavaScript(not jQuery)で解決する

Last updated at Posted at 2019-01-20

よくこういう記事の目次とかページ内の見出しに飛ぶようなリンクありますよね?
スクリーンショット 2019-01-20 23.50.32.png
こういうhrefに飛びたい位置の要素のid名を指定したリンクを「アンカーリンク」と呼ぶそうです。

ただこのリンク、ページ上部にfixedなどで固定したヘッダーがあるとうまく飛ばないことがよく起きます。
スクリーンショット 2019-01-20 23.53.05.png
巷では、スムーススクロールと併せてjQueryで解決する例が溢れているので、今回はこれをJavaScriptで解決してみます。

JavaScriptを使わなくても解決できる

「今回はこれをJavaScriptで解決してみます。」と言いましたが、基本的にはJavaScriptを使わなくても解決できます。

padding-top: 50px;
margin-top: -50px;

これを飛びたい先の要素(見出しなど)に指定すればいいわけですが、デザインなどの都合でどうしてもこれを適用できないとか、CSS調整するのめんどくさい時とかあると思います。
そういう時にCSS・jQueryなしで使えるコードを作ってみました。

実際のコード

document.addEventListener('window.onload', () => {
    let headH = document.getElementsByTagName('header')[0].offsetHeight + 10;  //ヘッダーの高さを取得
    mokujiLink(headH);
});
function mokujiLink(headH = 0) {
    for (let i = 0; i < document.querySelectorAll('a[href^="#"]').length; i++) {
        let lect = window.pageYOffset + document.getElementById(document.querySelectorAll('a[href^="#"]')[i].getAttribute("href").replace('#', '')).getBoundingClientRect().top - headH;
        document.querySelectorAll('a[href^="#"]')[i].setAttribute("onClick", 'window.scrollTo(0,'+lect+')');
        document.querySelectorAll('a[href^="#"]')[i].removeAttribute("href")
    }
}

document.querySelectorAll('a[href^="#"]')でページ内の全てのアンカーリンクを取得します。

飛ぶ位置を、ヘッダー要素の高さ分引いて調整することで被らないようにしています。

アンカーリンクの数だけfor文で「所定のid要素にscrollするonclick」をaddしているわけです。

シンプルですね。

ただ、TurbolinksやService Workerなど、ページの読み込みをXHRで行なっている場合は正しい動作をしないことがあるので、注意してください。

また、もっといいやり方があったら、ぜひコメント欄で教えてください。

ありがとうございました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?