スクロールでナビゲーション(ページ内リンク)のカレント表示【コピペOK】

こんにちは、現在フリーのweb製作者として働いているしょーご(@samuraibrass)と申します。

今回作るのはリンクのカレント表示です。

カレントさん
カレントさん
ちょっとわかりにくい…
カレントくん
カレントくん
つまり、特定要素に移動すると、リンク(ナビゲーション)に下線が付くってこと?
しょーご
しょーご
そういうことだね。

このようなカレント表示を作りたい方へ、コピペですむように、普段私が使っているコードを紹介します。

コードの詳細解説はしていません、今後追加する予定です

カレント表示コピペの仕方

まずは以下、codepenで動くものを公開しています。

See the Pen
current navigation
by samuraibrass (@samuraibrass)
on CodePen.


コピペの仕方ですが、まずjQueryを利用しますので読み込んでください。

その後、こちらのjsコードをjsファイルにコピペしてください。

codepeと同じjsコードです。

その1:jsファイルコピペ

$(function () {
  var set = 200;//ウインドウ上部からどれぐらいの位置で変化させるか
  var boxTop = new Array;
  var current = -1;
  //各要素の位置
  //position-nowは場所を取得したい対象の要素に付ける
  $('.position-now').each(function (i) {
    boxTop[i] = $(this).offset().top;
  });
  //最初の要素にclass="positiion-now"をつける
  changeBox(0);
  //スクロールした時の処理
  $(window).scroll(function () {
    scrollPosition = $(window).scrollTop();
    for (var i = boxTop.length - 1; i >= 0; i--) {
      if ($(window).scrollTop() > boxTop[i] - set) {
        changeBox(i);
        break;
      }
    };
  });
  //ナビの処理
  function changeBox(secNum) {
    if (secNum != current) {
      current = secNum;
      secNum2 = secNum + 1;//以下にクラス付与したい要素名と付与したいクラス名
      $('.nav-global li a').removeClass('link-current');

      //位置によって個別に処理をしたい場合 
      if (current == 0) {
        $('#top_link_js').addClass('link-current');
        // 現在地がsection1の場合の処理
      } else if (current == 1) {
        $('#about_link_js').addClass('link-current');
        // 現在地がsection2の場合の処理
      } else if (current == 2) {
        // 現在地がsection3の場合の処理
        $('#business_link_js').addClass('link-current');
      }
      else if (current == 3) {
        // 現在地がsection4の場合の処理
        $('#access_link_js').addClass('link-current');
      }
      else if (current == 4) {
        // 現在地がsection4の場合の処理
        $('#contact_link_js').addClass('link-current');
      }

    }
  };
});
$(function () {
  $('a[href^="#"]').click(function () {
    var adjust = -100;
    var speed = 500;
    var href = $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top + adjust;
    $("html, body").animate({ scrollTop: position }, speed, "swing");
    return false;
  });
});

この先いじるのは2行目と30~50行目あたりだけです。

ここを各々の環境に合わせてカスタマイズしていきます。

52行目からはスムーススクロールです。すでに導入している方は競合しないか、ご確認ください。

その2:HTMLの編集

position-nowクラスを取得したい要素につける

codepenを見ていただけるとわかりますが、各sectionにposition-nowというクラス名をつけています。

position-nowが見えたらカレント表示をナビにつけるためです。

各々取得したい要素(大体はdivかsectionだと思いますが)全てにposition-nowとつけてください。

<section class="position-now" id="top">
      <h2>Topタイトル</h2>
      <p>Topコンテンツです</p>
    </section>

ナビゲーションに固有の名前(id)を振る

codepenでは

  • topにはtop_link_js
  • aboutにはabout_link_js

などid名をつけています。クラスを付与してカレント表示するためにわかりやすいid名をつけてください。

jsで操作するものには、上記のように_jsとid名をつけるのがおすすめです。

<nav class="nav-global">
          <ul class="flexbox">
            <li><a href="#top" id="top_link_js">TOP</a></li>
            <li><a href="#about" id="about_link_js">ABOUT</a></li>
            <li><a href="#business" id="business_link_js">BUSINESS</a></li>
            <li><a href="#access" id="access_link_js">ACCESS</a></li>
            <li><a href="#contact" id="contact_link_js">CONTACT</a></li>
          </ul>
        </nav>

ページ内リンクをつける

ナビゲーションとスクロール先の要素を紐づけてください。

topならhrefに#top、そしてtopコンテンツにid=”top”とつけることで、ページ内リンクとして機能します。

その3:cssの編集

codepenを見ていただくとわかりますが、カレント表示はlink-currentというクラスを当てることで、下線を表現しています。

ですので、link-currentというクラス名で、カレント表示のcssをお好みで描いてください。

codepenのサンプルでは

.link-current {
  border-bottom: 2px solid #fff;
}

としています。

その4:jsファイルの編集

それでは、最後にコピペしたjsファイルを編集し、動くようにしましょう。

まず27行目はカレント表示させたい要素を指定してください。

.nav-global li a

という部分です。

各々のナビゲーション、リンクを指定してください。

その後、以下の$(‘#top_link_js’)や$(‘#about_link_js’)の部分を、先ほど自分でHTMLに書いたid名に変更してください。

//位置によって個別に処理をしたい場合 
      if (current == 0) {
        $('#top_link_js').addClass('link-current');
        // 現在地がsection1の場合の処理
      } else if (current == 1) {
        $('#about_link_js').addClass('link-current');
        // 現在地がsection2の場合の処理
      } else if (current == 2) {
        // 現在地がsection3の場合の処理
        $('#business_link_js').addClass('link-current');
      }
      else if (current == 3) {
        // 現在地がsection4の場合の処理
        $('#access_link_js').addClass('link-current');
      }
      else if (current == 4) {
        // 現在地がsection4の場合の処理
        $('#contact_link_js').addClass('link-current');
      }

一応解説すると、if文でtop_link_jsに位置にスクロールしたら、link-currentをつけるという処理です。

その後elseifで#about_link_jsや#business_link_jsなどあるだけ繋げます。

また、ナビゲーションリンクが5つより多い場合は、

else if (current == 5) {
        // 現在地がsection5の場合の処理
        $('#hoge').addClass('link-current');
      }
      else if (current == 6) {
        // 現在地がsection6の場合の処理
        $('#hogehoge').addClass('link-current');
      }

などと、currentの数字を増やしていくと、いくらでも増やすことができます。

逆に減らすこともできます。

その5:微調整

もしlink-currentクラスを付与するタイミングをずらしたい場合は、

var set = 200;//ウインドウ上部からどれぐらいの位置で変化させるか

この部分をいじってみてください。

あと、このヘッダーは固定ヘッダーでheightは80pxですが、heightによってスクロール先でズレが生じるかもなので、その際は

$(function () {
  $('a[href^="#"]').click(function () {
    var adjust = -100;
    var speed = 500;
    var href = $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top + adjust;
    $("html, body").animate({ scrollTop: position }, speed, "swing");
    return false;
  });
});

のadjustの数値をいじって調整してみてください。

この部分はスムーススクロールになります。

カレント表示を使い回す

とりあえずカレント表示を使いまわしたい方向けに書きました。

汎用性のあるコードなので、ぜひカレント表示の際は使ってみてください。

まとめ

  1. jsコードコピペ
  2. HTMLで位置を取得する要素にposition-nowクラス付与し、ページ内リンクもつける、ナビゲーションに固有id名
  3. cssでlink-currentで付与したいcss処理(下線など)を書く
  4. jsを固有id名に書き換えて、link-current付与できるようにする
  5. 微調整