javascriptを使って、一定のスクロール量(300px)ごとに、固定ヘッダーのロゴの文字が、七色に変化するようなアクションをさせたいです。
スクロール量が
・初期状態 赤
・300pxで 橙
・600pxで 黃
・900pxで 緑
・1200pxで 青
・1500pxで 藍
・1800pxで 紫
で、1800pxスクロールすると7色目に到達、次の300px(=2100px目)では最初の「赤」に戻って、スクロール出来る限り「七色の変化が永久ループする」といった具合です。
ググってみても、特定のスクロール量ごとに色を変化させる方法が見つからなかったので、自分でも考えてみたのですが、例えば、
.color_1~.color_7の7つのクラスを用意して、スクロール量100pxごとに、クラス末尾の数字を1つカウントアップさせて、それをロゴ要素に付与する、という感じです。これを踏まえて、以下のようなコードを書きました。
HTML
1<div style="height:20000px;"> 2 <div id="logo" class="color_1">test</div> 3</div>
CSS
1#logo { position: fixed; left: 0; top: 0;} 2.color_1 { color: #c00;} 3.color_2 { color: #FF8E00;} 4.color_3 { color: #F0FF00;} 5.color_4 { color: #00FF05;} 6.color_5 { color: #1015FF;} 7.color_6 { color: #214A4E;} 8.color_7 { color: #8C15FF;}
JS
1var scroll; 2var current; 3var count = 1; 4 5$(window).scroll(function(){ 6 scroll = $(window).scrollTop(); 7 current = (scroll % 300); 8 9 // もし、スクロール量が300pxになったらクラスのカウントを1つアップさせて、ロゴ要素に(現在のクラスを削除後に)カウントアップさせたクラスを付与。※クラスのカウントが7だった場合は、1に戻す 10 if (current == 0) { 11 if (count < 7) { 12 count++; 13 $('#logo').removeClass().addClass('color_' + count); 14 } 15 else if(count == 7) { 16 count = 1; 17 $('#logo').removeClass().addClass('color_' + count); 18 19 } 20 } 21});
上記コードで、思っていた通りの動きは出来たのですが、3つの課題が出てきました。
それは、
・スクロールが止まるまで、スクリプトが実行されない
・スクロールが止まった時点で、300で割り切れないスクロール量の位置だと、スクリプトが実行されない
・スクロールを上に戻していく場合は、color_のクラス名をカウントダウンして戻していきたいが出来ない
です。
これをどう解決すればいいのか、ご教示いただけると幸いです。
よろしくお願いいたします。
●追記
上記の確認方法についてですが、
・chomeで上記コードを記述したページを表示
・Windows環境で、F12ボタン→開発者ツールを開いてコードが変わる様子を監視
・スクリプトに、$('p').text(scroll); を追加して、スクロール量を画面にリアルタイムで表示させるようにした
という環境でおこないました。
スクロール中もスクロール量の値は随時変動しているのは見れたのですが、.color_のクラスが付与、切り替わるタイミングは、スクロールが止まった時に「300で割り切れた場合のみ」でした。要は、自分が書いているスクリプトが「スクロールが止まった時点で行われる」ということは認識しております。
なので、リアルタイムにそれを処理する方法があるのかと思い、その解決策があればご教示いただきたい次第です。
●追記 21/09/24 09:24
m.ts10806さんにご教示いただいた内容を元に、「直前のscrollTopの位置」と「現在のスクロールの位置」を比較して、上下の判定を行い、カウントをアップ/ダウンさせるスクリプトを書いてみました。
javascript
1var posBefore; 2var posAfter; 3var current; 4var count = 1; 5var color = 1; 6 7posBefore = $(window).scrollTop(); 8 9$(document).on("scroll",$(window),function(){ 10 posAfter = $(this).scrollTop(); 11 12 // スクロール開始位置がスクロール後より大きい 13 if (posAfter < posBefore) { 14 console.log('うえ'); /* チェック用 */ 15 current = (posAfter * 300); 16 17 if (color > 1) { 18 $('#logo').removeClass().addClass('color_' + color); 19 color--; 20 } 21 else if(color == 1) { 22 $('#logo').removeClass().addClass('color_' + color); 23 color=7; 24 } 25 // スクロール開始位置がスクロール後より小さい 26 }else{ 27 console.log('した'); /* チェック用 */ 28 current = (posAfter * 300); 29 30 if (color < 7) { 31 $('#logo').removeClass().addClass('color_' + color); 32 color++; 33 } 34 else if(color == 7) { 35 $('#logo').removeClass().addClass('color_' + color); 36 color=1; 37 } 38 39 } 40 41 //開始位置をスクロール後の位置に書き換える 42 posBefore = posAfter; 43});
ただし、ご教示いただいた内容のうち、以下部分が理解できておらず、
javascript
1current = (count * 300);
上下にスクロールさせる際、スクロール量の増減、color_の増減は出来ているっぽいのですが、300pxごとの変化が出来ず、もっと狭いスパンでcolor_の値が変化していってる状態でした。。