どうもRyokutyaです。
今回は、「追従さるサイドバー」の最終回です。
前回、作ったif文に処理を記述するところから説明していきます。
目次
if文の処理を記述することで、追従するサイドバーは完成します。
今回の追従するサイドバーは条件によってleft_followのpositionを変更することで追従のon,offを切り替えています。
あらかじめ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_followとend_followをつけ外しすることで追従のon,offを切り替えています。
content_followを付与することで追従させることができますが、このままでは、positionがfixedになったときに横幅がいっぱいに広がってしまいます。
これを修正するために、ページが読み込まれた時のleft_followの幅を取得し、content_followを付与した際に幅を取得した値に変更する必要があります。
left_followの幅を取得するには、innerWidthメソッドを使用します。
innerWidthメソッドは対象要素.innerWidth()とすることで対象要素のpaddingを含んだ幅を取得できます。
var leftTargetWidth=$('.left_follow').innerWidth();
それでは、いよいよ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);
今回で「追従するサイドバー」は完成です。
コピペして使用する場合は「追従するサイドバー」の第一回記事「サイドバーを追従させよう!」にコードを載せているのでご利用ください。
この記事が誰かのお役に立ててれば幸いです。
それでは今回はこのあたりで(^^)/
緑茶のカテゴリー
(29)
(1)
コメントを残す