スクロールでサイドバーを「ぬるっと」固定する

Filed under: JavaScript — kdcs @ 20年6月23日 火曜日

jQuery使います。

<div id="content">
<div id="contentArea" class="inner">
<div id="main">
メインエリア
</div><!--/#main-->
<div id="aside">
<div id="asideBox">
サイドバー
</div><!--/#asideBox-->
</div><!--/#aside-->
</div><!--/#contentArea-->
</div><!--/#content-->

javascript

//サイドバー固定 -------------------------------------------
$(function($){
    var content = $("#contentArea");
    var sidebar = $("#aside");
    var sticked = $("#asideBox");

    // サイドバーの位置
    var sidebar_top = sidebar.offset().top;
    // 固定するコンテンツの元々の位置
    var sticked_original_top = sticked.offset().top;
    // 固定するコンテンツの高さ
    var sticked_height = sticked.height();

    $(window).on('scroll resize', function(){ // スクロールかリサイズ時
        // 現在の位置
        var scrollTop = $(document).scrollTop();
        // メインコンテンツ最後尾
        var content_bottom = content.offset().top + content.height();

        if ((scrollTop > sticked_original_top) && (scrollTop < content_bottom - sticked_height)){
            // 現在位置が、初期位置より下で、メインコンテンツ最後尾より上なら、画面上部にサイドバーを固定
            sticked.css({'position': 'fixed',
                'top': 0, 
                'width': sidebar.width()
            });
        } else if(scrollTop >= content_bottom - sticked_height){
            // 現在位置がメインコンテンツ最後尾より下なら、メインコンテンツ最後尾にサイドバーを位置させる
            sticked.css({'position': 'absolute',
                'top': content_bottom - sticked_height - sidebar_top,
                'width': sidebar.width()
            });
        } else {
            // 現在位置が初期位置より上なら、何もしない
            sticked.css({'position': 'static'});
        }
    });
});

※この記述ではレスポンシブでサイドバーの横幅が整わなくなってしまうので以下に修正
・ぬるっと動かしたいのでtransition追加
・初期位置をstaticからrilativeに変更
・widthを外しmax-widthで調整(max-widthはcssで指定したasideのパーセント指定幅時のpxサイズ)

追加 2020.7.12
投稿内容が少なくサイドバーの方が高さがある場合は動かさないという記述
・7行目 content_height
・16~19行目 if sticked_height > content_height
・20行目 ifをelse if に変更
※以下は途中経過のコード

//サイドバー固定 -------------------------------------------
$(function($){
    var content = $("#contentArea");
    var sidebar = $("#aside");
    var sticked = $("#asideBox");

    var content_height = content.height();
    var sidebar_top = sidebar.offset().top;
    var sticked_original_top = sticked.offset().top;
    var sticked_height = sticked.height();

    $(window).on('scroll resize', function(){
        var scrollTop = $(document).scrollTop();
        var content_bottom = content.offset().top + content.height();

        if (sticked_height > content_height) {
            sticked.css({'position': 'relative',
                'top': 0
           });
       } else if ((scrollTop > sticked_original_top) && (scrollTop < content_bottom - sticked_height)){
            sticked.css({'position': 'fixed',
                'top': 70, 
                'max-width': '248.4px'
            });
        } else if(scrollTop >= content_bottom - sticked_height){
            sticked.css({'position': 'absolute',
                'top': content_bottom - sticked_height - sidebar_top,
                'max-width': '248.4px'
            });
        } else {
            sticked.css({'position': 'relative','top': 0,'transition': '0.5s'});
        }
    });
});

※画面横幅を広くしたり狭くしたりしてスクロールするとasideBoxの挙動がおかしいことが多々あり、
 最終的に以下の記述にした。
※#mainの高さも必要なので追加

※以下が最終形

//サイドバー固定 -------------------------------------------
$(function($){
    var content = $("#contentArea");
    var main = $("#main");
    var sidebar = $("#aside");
    var sticked = $("#asideBox");

    var content_height = content.height();
    var main_height = main.height();
    var sidebar_top = sidebar.offset().top;
    var sticked_original_top = sticked.offset().top;
    var sticked_height = sticked.height();
    var difference = 70;

    $(window).on('scroll resize', function(){
        var scrollTop = $(document).scrollTop();
        var content_bottom = content.offset().top + content.height();

        if (sticked_height > main_height) {
            sticked.css({'position': 'relative',
                'top': 0,
            });
        } else if ((scrollTop > sticked_original_top) && (scrollTop < content_bottom - sticked_height)){
            sticked.css({'position': 'fixed',
                'top': 70, 
                'width': sidebar.width(),
                'max-width': sidebar.width(),
            });
        } else if(scrollTop >= content_bottom - sticked_height){
            sticked.css({'position': 'absolute',
                'top': content_bottom - sticked_height - sidebar_top + 70,
                'width': sidebar.width(),
                'max-width': sidebar.width(),
                'transition': '0.0s'
            });
        } else {
            sticked.css({'position': 'relative','width': '100%','max-width': sidebar.width(),'top': 0,'transition': '0.5s'});
        }
    });
});

cssでwidthやmax-widthの部分で「sidebar.width()」を使用し可変させることでレスポンシブに対応させた。

サイト内検索

カテゴリー

最近の投稿

« |スクロールでサイドバーを「ぬるっと」固定する| »
↑上に戻る