menu

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

H&Rブログ > JavaScript > サイドバー > 追従するサイドバーを完成させる!

追従するサイドバーを完成させる!

JavaScript




どうもRyokutyaです。
今回は、「追従さるサイドバー」の最終回です。
前回、作ったif文に処理を記述するところから説明していきます。

目次

if文の処理を考える

if文の処理を記述することで、追従するサイドバーは完成します。
今回の追従するサイドバーは条件によってleft_followのpositionを変更することで追従のon,offを切り替えています。

追従のon,offを切り替えるcss

あらかじめcssで特定のクラス名に異なるpositionを設定して準備しています。

//=================================================//
//javascript用
//=================================================//
.content_follow{
    position: fixed;
    top:0;
}

.end_follow{
    position: absolute;
    bottom: 0px;
    
}

content_followと言う名前のクラスにposition:fixed;を付与しています。
このクラスを付与することで、positionがfixedになります。
positionがfixedになるとスクロールしても位置が固定されたままになります。
end_followと言う名前のクラスにはposition:absolute;を付与してあります。
all_coverにposition:relative;が設定してあるのでall_coverを基準にend_followの座標が決定されます。
bottom:0;としているため、end_followが付与された要素はall_coverの一番下に配置されます。

このcontent_followend_followをつけ外しすることで追従のon,offを切り替えています。

left_followの幅を取得する

content_followを付与することで追従させることができますが、このままでは、positionがfixedになったときに横幅がいっぱいに広がってしまいます。

これを修正するために、ページが読み込まれた時のleft_followの幅を取得し、content_followを付与した際に幅を取得した値に変更する必要があります。
left_followの幅を取得するには、innerWidthメソッドを使用します。
innerWidthメソッドは対象要素.innerWidth()とすることで対象要素のpaddingを含んだ幅を取得できます。

var leftTargetWidth=$('.left_follow').innerWidth();

if文の中の処理

それでは、いよいよif文の中の処理を説明していきます。
条件3:footerPosition<leftFollowHeight+scrollAmount

leftFollowHeight+scrollAmountの値がこの範囲の時はleft_followに、それ以上追従せずに止まって欲しいので、left_followにend_followクラスを付与します。
end_followクラスを付与することで、left_followのpositionがabsoluteになります。
bottom:0;としているため、all_coverの一番下にleft_followが配置されます。
こうすることで、left_followの追従を停止することができます。
後に説明しますが、条件3になるときは、left_followにcontent_followクラスが付与されています。
条件3の時に、content_followクラスがついているとcssがうまく切り替えないので、removeClassを使って除去しています。

//条件3
if(footerPosition > leftFollowHeight+scrollAmount){
    leftFollow.addClass('end_follow');
    leftFollow.removeClass('content_follow');
}

条件2:leftTargetPosition < scrollAmount && footerPosition>leftFollowHeight+scrollAmount

条件2の範囲にleft_followがあるときはスクロールに合わせて追従して欲しいので、content_followクラスを付与します。
content_followクラスを付与すると、cssのpositionがfixedになるため、left_followはスクロールに合わせて追従するようになります。
「left_followの幅を取得する」の項目でも説明しましたが、positionがfixedになると、widthが変わってしまい横に広がってしまうので、JavaScriptでwidthを指定しています。
end_followクラスがあるとうまく動作しなくなるため、removeClassで除去しています。

//条件2
if(leftTargetPosition < scrollAmount && footerPosition>leftFollowHeight+scrollAmount){
    leftFollow.addClass('content_follow');
    leftFollow.removeClass('end_follow');
    $('.content_follow').css('width',leftTargetWidth+'px');
}

条件1:sideTargetPosition > scrollAmount

scrollAmountが条件1の範囲にある時は、left_followは初期座標にあるようにしたいので、content_followクラスとend_followクラスの両方のクラスをremoveClassで除去しています。

//条件1
if(leftTargetPosition > scrollAmount){
    leftFollow.removeClass('content_follow');
    leftFollow.removeClass('end_follow');
}

これで完成です……
左側は。
右側のサイドバーを追従させるには右側用のコード作成しないといけません。

右サイドバー部分と共通部分

右サイドバーを追従させるコードは左側のコードとほぼ同じです。
変数の名前と対象要素が変わっているだけで内容は全て同じなので説明は省きます。
下記に左側と右側のデータ取得の部分をまとめ記述しているので、見比べてください。

//**** 左サイドバー準備 ****//
    //left_targetが1つもないと.topの部分でエラーがでるためif文にいれている
    if( $('.left_side').find('.left_target').length ){
        var leftNextBrother=$('.left_target').nextAll('div');
        var leftNextBrotherLength=leftNextBrother.length;
        for(i=0; i<leftNextBrotherLength; i++){
            leftNextBrother[i].classList.add('left_target');
        }
        $('.left_target').wrapAll('<div class="left_follow">');
        var leftTargetPosition=$('.left_follow').offset().top;
        var leftTargetWidth=$('.left_follow').innerWidth();
        var leftFollow=$('.left_follow');
        //left_followの高さ
        var leftFollowHeight=$('.left_follow').height();
    }
    
    //**** 右サイドバー準備 ****//
    //right_targetが1つもないと.topの部分でエラーがでるためif文にいれている
    if( $('.right_side').find('.right_target').length ){
        var rightNextBrother=$('.right_target').nextAll('div');
        var rightNextBrotherLength=rightNextBrother.length;
        for(i=0; i<rightNextBrotherLength; i++){
            rightNextBrother[i].classList.add('right_target');
        }
        $('.right_target').wrapAll('<div class="right_follow">');
        var rightTargetPosition=$('.right_follow').offset().top;
        var rightTargetWidth=$('.right_follow').innerWidth();
        var rightFollow=$('.right_follow');
        //right_followの高さ
        var rightFollowHeight=$('.right_follow').height();
    }

    
    //footerの高さを取得
    var footerPosition=$('footer').offset().top;

コード見ると左側と同じことを右側用で書き換えているだけということが解るかとおもいます。
これで、右側の準備は完了なので、if文も右側用に書き換えたものをもう一つ用意するだけなのですが、それでは芸がないので、if文の部分を関数でひとまとめにして、呼び出す際に右用と左用の引数を渡すことで2回書くことを避けています。

 window.onscroll=function(){
        //現在のスクロール量を取得
        var scrollAmount=window.pageYOffset;
        
        function sideFollow(sideTargetPosition,sideTargetWidth,sideFollowHeight,sideFollow){
            
            //条件1
            if(sideTargetPosition > scrollAmount){
                sideFollow.removeClass('content_follow');
                sideFollow.removeClass('end_follow');
            }

            //条件2
            if(sideTargetPosition < scrollAmount && footerPosition>sideFollowHeight+scrollAmount){
                sideFollow.addClass('content_follow');
                sideFollow.removeClass('end_follow');
                $('.content_follow').css('width',sideTargetWidth+'px');
            }

             //条件3
            if(footerPosition < sideFollowHeight+scrollAmount){
                sideFollow.addClass('end_follow');
                sideFollow.removeClass('content_follow');
            }

        }

        //======= 右サイドの分岐 =======//
        sideFollow(rightTargetPosition,rightTargetWidth,rightFollowHeight,rightFollow);

        //======= 左サイドの分岐 =======//
        sideFollow(leftTargetPosition,leftTargetWidth,leftFollowHeight,leftFollow);

おわりに

今回で「追従するサイドバー」は完成です。
コピペして使用する場合は「追従するサイドバー」の第一回記事「サイドバーを追従させよう!」にコードを載せているのでご利用ください。
この記事が誰かのお役に立ててれば幸いです。
それでは今回はこのあたりで(^^)/




コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

アーカイブ

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

アーカイブ