TEORICO

【jQuery】スクロールしたらついてくるナビゲーション

【jQuery】スクロールしたらついてくるナビゲーション

一定量スクロールしたらついてくるナビゲーション

一定量スクロールしたら設置しているグローバルナビがついてくるようにする方法です。

JavaScript版はこちらから

最初から

position:fixed;

にしておけば間違いなくついてくるのですが、ヘッダーがあって、メインビジュアルがあって、ナビゲーションがある場合は最初からfixedにしておくと少し問題があります。

やり方としても、クラス名を付け外しする方法と、jQueryでCSSを変更を加える方法があります。

今回はjQueryでCSSを変更する方法です。

注意点も含めサンプルを置いておきます。

実際に適用しているサンプルはこちらから

 

HTMLとjQuery

サンプルで使用しているHTML

<header class="gloval__header">
  <h1><a href=""><img src="images/logo.png" alt="ロゴ画像が入ります。"></a></h1>
  <nav class="gloval__nav">
    <div class="gloval__nav--switch"> <span></span> </div>
    <ul class="gloval__nav--list">
      <li><a href="">Home</a></li>
      <li><a href="">Blog</a></li>
      <li><a href="">About</a></li>
      <li><a href="">Contact</a></li>
    </ul>
  </nav>
</header>
<main>
  <div class="main__wrapper">
    <p>メインコンテンツ部分</p>
  </div>
</main>
<footer class="gloval__footer"> 
  <small>Copyright</small> 
</footer>

headerがあり、その中にグローバルナビゲーションがあります。

このブログサイトのheader部分です。

そしてメインコンテンツ部分である、mainがあります。

最後にfooterといういたってシンプルなHTMLです。

CSSに関してですが、特別なことはしていないので割愛します。

検証ツール(デベロッパーツール)などで確認していただいても構いません。

サンプルで.main__wrapperに対して、heightをつけているのはスクロールさせたいのでわざとです。

 

次にjQueryです

$(function () {
  var glovalNav = $('.gloval__nav'); // グローバルナビゲーションのセレクタ 
  var navHeight = glovalNav.outerHeight(true); // ナビゲーションのheight(marginやpadding,box-shadowも含む)
  var navOffset = glovalNav.offset().top; // ブラウザの一番上からナビゲーションまでの位置

  // スクロールした時 
  $(window).scroll(function () { // スクロールがナビゲーション位置に来たら 
    if ($(this).scrollTop() > navOffset) { // ナビゲーションをfixedさせる
      glovalNav.css({
        'position': 'fixed',
        'top': 0,
        'width': '100%',
      }); // ここは重要な部分で、 fixedするとその分高さがなくなるので、 margin - topを高さ分つけてあげます。 
      $('.main__wrapper').css('margin-top', navHeight);
    } else { // ifのtrueでない場合、 つまり、 ナビゲーション位置に来ていない時は static で元に戻す。
      glovalNav.css('position', 'static');
      $('.main__wrapper').css('margin-top', 'auto');
    }
  });
});

基本的にはコメントで書いている通りです。

$(window).scrollでスクロールした時をきっかけとしてjQueryを動作させることができます。

重要な部分として、

outerHeightメソッドを使用している点

outerHeight(true)とします。outerHeight()ではなく、必ず引数にtrueを追加してください。

そうすることでheightだけでなく、marginやpadding,borderやbox-shadowまでも含んだ高さを取得できます。

fixedするとabsoluteと同じで指定した部分が浮くような状態になるので、その分高さを失ってしまいます。

ですので、メイン部分にmargin-topを高さと同じpx数つけてあげることでガタつきを防ぎます。

これがないと、ガタガタしてメインコンテンツの最初の部分が少し見えなくなりますので注意してください。

jQueryでCSSを変更する方法ですが、次のように記述します。

$('セレクタ').css('変更したいプロパティ','数値など');

もし複数一気に変更したい場合は

$('セレクタ').css({
  '変更したいプロパティ': '数値など',
  '変更したいプロパティ': '数値など',
  '変更したいプロパティ': '数値など',
});

カッコの中に波カッコを追記し、区切りがカンマではなくコロンになります。

そして、カンマで区切ります。

これで完成です。

 

まとめ

今回書いたソースはCSSを変更するやり方ですが、この変更しているCSSをクラスで作っておいてあげればaddClassとremoveClassでクラスの付け外しを行いfixedさせるということも可能です。

注意点を追記しておきます。(2017/11/01追記)

bxSliderなどのプラグインを使用すると、きちんとした高さが取れないことがあります。

その際は$(function()内ではなく、$(window).on(‘load’,function()でoffsetを取得する、またはsetIntervalやsettimeoutなどを利用することで上手に取れます。

ただし、どちらのメソッドも繰り返し処理を行うので負荷をかけてしまいます。

clearIntervalやclearTimeoutを使用して1度だけなどにしておくと良いかもしれません。

 

今回使ったメソッド

.outerHeight(true);
.offset().top;
.scrollTop();
.css();