縦長のページでページ内リンクのナビゲーションを設置している場合に、スクロール位置によって現在位置をカレント表示させる方法をご紹介いたします。
言葉にするといまいちわかりにくいですが、以下に簡単なデモを用意しましたので、ご参照いただければと思います。
このように、上部にあるナビゲーションをハイライトさせ、どこまでスクロールしているかを明確にします。
ページ内リンクのナビゲーションをスクロール位置によってカレント表示させる方法
ナビゲーションとリンク先要素のマークアップ
HTMLでは、ページ内リンクとリンク先の要素をマークアップします。
<ul class="step"> <li><a href="#step1">ステップ1</a></li> <li><a href="#step2">ステップ2</a></li> <li><a href="#step3">ステップ3</a></li> </ul> <section id="step1"> <h3>ステップ1</h3> <p>ステップ1~</p> </section> <section id="step2"> <h3>ステップ2</h3> <p>ステップ2~</p> </section> <section id="step3"> <h3>ステップ3</h3> <p>ステップ3~</p> </section>
スクリプトの実行
スクロール位置によってナビゲーションにクラスを追加するスクリプトを記述します。記述場所は</body>の直前でOKです。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> $(function() { var stepMenu = function() { var array = { '#step1': 0, '#step2': 0, '#step3': 0 }; var $globalNavi = new Array(); for (var key in array) { if ($(key).offset()) { array[key] = $(key).offset().top - 10; $globalNavi[key] = $('.step li a[href="' +key+ '"]'); } } $(window).scroll(function () { for (var key in array) { if ($(window).scrollTop() > array[key] - 10) { $('.step li a').each(function() { $(this).removeClass('current'); }); $globalNavi[key].addClass('current'); } } }); } stepMenu(); }); </script>
最初にjQuery本体を読み込み、「stepMenu」という関数を定義して実行しています。
最初に#step1~3までの距離を計算して、スクロール位置がその距離に達したら”.current”というクラスをナビゲーションのa要素に追加しています。
CSSで見た目の調整
HTMLとスクリプトの記述ができたら、あとはCSSで見た目を整えましょう。.currentクラスが追加された時の背景色やテキスト色を変更すれば、ページ内リンクナビゲーションのカレント表示の完成です。
参考までにデモページのCSSを掲載しておきます。
body { margin: 0; padding: 100px 0 0; } main { width: 960px; margin: 0 auto; } header { position: fixed; top: 0; } section { margin: 300px 0; } .step { margin: 0; padding: 0; list-style: none; display: flex; justify-content: center; } .step a { display: inline-block; padding: 15px 30px; border: solid 1px #aaa; color: #aaa; background: #fff; text-decoration: none; } .step a:hover, .step a.current { background: #aaa; color: #fff; }
ナビゲーションが画像リンクの場合
ナビゲーションの実装に画像を使用している場合は、画像を差し替えることでカレント表示させることもできます。例えば、それぞれのナビゲーションをstep〇_on.pngとstep〇_off.pngといったように、オンオフの画像を切り替えたい場合は、以下のようにスクリプトを記述します。
<script> $(function() { var stepMenu = function() { var array = { '#step1': 0, '#step2': 0, '#step3': 0 }; var $globalNavi = new Array(); for (var key in array) { if ($(key).offset()) { array[key] = $(key).offset().top - 10; $globalNavi[key] = $('.step li a[href="' +key+ '"]'); } } $(window).scroll(function () { for (var key in array) { if ($(window).scrollTop() > array[key] - 10) { $('.step li a').each(function() { $(this).removeClass('current'); $(this).children().attr('src', $(this).children().attr("src").replace(/^(.+)_on(\.[a-z]+)$/, '$1_off$2')); }); $globalNavi[key].addClass('current'); $(".step .current img").attr('src', $(".step .current img").attr("src").replace(/^(.+)_off(\.[a-z]+)$/, '$1_on$2')); } } }); } stepMenu(); }); </script>
「$(“.step .current img”).attr(‘src’, $(“.step .current img”).attr(“src”).replace(/^(.+)_off(\.[a-z]+)$/, ‘$1_on$2’));」では、”_off.png”から”_on.png”へ、「$(this).children().attr(‘src’, $(this).children().attr(“src”).replace(/^(.+)_on(\.[a-z]+)$/, ‘$1_off$2’));」では、”_on.png”から”_off.png”へ画像を切り替えています。
あとがき
ページ内ナビゲーションのカレント表示は、手順を説明しているページなどで見かけますね。割と簡単に実装できますので、縦長のページなどでぜひお試しください。