スクロールしてもコンテンツの範囲内を固定されて追従するサイドメニューの作り方【jQuery】

プロモーションが含まれています

スクロールしてもコンテンツの範囲内を固定されて追従するサイドメニューの作り方【jQuery】

jQueryで、スクロールしてもコンテンツの範囲内を固定されて、範囲を超えたらその位置で待ってる忠犬のような追従するサイドメニューの作り方

デモはこちら

【jQuery】スクロールしてもコンテンツの範囲内を固定されて追従するサイドメニューの作り方デモ

ナビゲーションメニュー関連記事

2カラムのhtml

html

<div class="wrap">
    <div id="left"><ul></ul></div>
    <div id="main"></div>
</div>

2カラムを作成し、#leftがスクロールしても固定されて追従するメニュー部分です。

サイドナビのcss

css

#left{
    width: 200px;
    margin-right: 40px;
    background-color: #F3F3F3;
    float: left;
    position: relative;
    top: 0;
}
#left ul{
    list-style: none;
    padding: 0;
    margin: 0;
    border-top: 1px solid #888;
}
#left ul li{
    height: 50px;
    line-height: 50px;
    text-align: center;
    border: 1px solid #888;
    border-top: none;
}
#main{
    width: 540px;
    padding: 10px;
    background-color: #fff;
    float: right;
    position: relative;
    top: 0;
    border: 1px solid #888;
    box-sizing: border-box;
}

まず、コンテンツとサイドナビを作ります。この時点ではスクロールするとサイドナビが置いて行かれてしまう状態なのでjsで書いていきます。

サイドナビ用のJavaScript

JavaScript

$(document).ready(function() {

    var bet1stheight = $("#left").height(); //ナビの高さ
    var between1st = $("#main").offset().top; //コンテンツのページ上部からの位置
    var between2nd = $("#main").outerHeight(); //コンテンツの高さ
    var endline = between2nd + between1st - bet1stheight; //追従終了の位置

    $(window).scroll(function() {
        var scrollY = $(window).scrollTop(); //現在のスクロール位置
        
        if(scrollY <= between1st){
            $("#left").css({
                "position": "relative",
                "top" : "auto",
                "bottom" : "auto"
            });
        }else if (scrollY > between1st && scrollY < endline) {
            $("#left").css({
                "position": "fixed",
                "top" : 0,
                "bottom" : "auto"
            });
        }else{
            $("#left").css({
                "position": "absolute",
                "top" : "auto",
                "bottom" : "0px"
            });
        }
    });
});

まず、ナビとコンテンツの位置と高さを取得します。
それらを計算してコンテンツに追従する範囲を割り出します。

高さの取得に関しては、 height()で取得できない!marginやpaddingを含めた高さを取得する【jQuery】で解説しています。

height()で取得できない!marginやpaddingを含めた高さを取得する【jQuery】
jQueryのheight()だと実はmarginやpaddingやborderを含めた高さが取得できないってことに気づいた話jQuery関連記事height()で取得する値cssこの要素の場合、height()で取得する値は「50」になる

次にスクロールする度に現在のスクロール位置を調べて範囲のどこに当てはまるかでサイドナビのcssを変更するだけです。

範囲より上ならrelative
範囲の中ならfixed
範囲より下ならabsoluteで指定しています。

範囲より下の場合、範囲の一番上からの位置を取得してtopの位置を指定しなきゃだなとか思ってたんですけど、bottom:0にするだけで余計な処理もいらないことに気づいたので他のパターンにも、bottom:autoで入れてあります。

たったこれだけで忠犬ナビが手に入ります。

ナビゲーションメニュー関連記事

コメント

  1. ななし より:

    追従サイドバーを設置するために探していましたが参考になりました。
    ただ、レスポンシブじゃない場合にウィンドウの画面幅が短く横スクロールが発生して横移動するとサイドバーの位置がずれたり被ったりします。
    縦スクロールはposition: fixedで横スクロールはposition: absoluteで固定させるために
    $(window).scrollLeft())とかで色々と試していますがうまく行きません。

  2. むぅ より:

    http://mugen00.moo.jp/sample/js_scroll_fixmenu/js_scroll_fixmenu2.html
    こういう感じですかね?
    常にposition: absoluteで置いておけば問題ないと思います。
    ただスクロールするたびに位置を移動させるのでサイドナビがプルプルするのが私的には気になります。
    transitionで動きを付けるとまだましになりますがこれはこれで不快ですね笑

    レスポンシブ対応するのが一番かと思います。

タイトルとURLをコピーしました