LP(ランディングページ)などでよく使われている、ある特定のエリアに差し掛かった時にパッと色が変わるナビゲーションの実装をしていきます。
今回は、セクションが画面に登場する度に、それに応じたid指定のサイドメニューの色が変わる効果を例にあげますが、そうでない場合にも応用が効くと思います。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <main> <section id=“to_section1”>1</section> <section id=“to_section2”>2</section> <section id=“to_section3”>3</section> <section id=“to_section4”>4</section> <section id=“to_section5”>5</section> <section id=“to_section6”>6</section> </main> <aside class=“sidebar”> <ul> <li><a href=“#to_section1”>section1</a></li> <li><a href=“#to_section2”>section2</a></li> <li><a href=“#to_section3”>section3</a></li> <li><a href=“#to_section4”>section4</a></li> <li><a href=“#to_section5”>section5</a></li> <li><a href=“#to_section6”>section6</a></li> </ul> </aside> |
メインカラムとサイドカラムです。
メインカラムにはidを指定します。
そこにページ内リンクを設定する要領で、サイドメニューのにもメインカラムのidへリンクを指定します。
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <style> body , html{ margin: 0; padding: 0; font–family: century gothic; } main{ width: 70%; float: left; } aside{ width: 30%; float: right; } li{list–style:none;} section{ height: 500px; padding: 250px 0; text–align: center; font–size: 200px; color: #fff; } section:nth–child(odd){ background–color: #cfc; } section:nth–child(even){ background–color: #ccf; } .sidebar{ position: fixed; right: 0; } .sidebar li a{ padding: 10px 30px; margin–bottom: 10px; background–color: #ccc; font–size: 30px; display: block; –webkit–transition: all .3s; –o–transition: all .3s; transition: all .3s; } .sidebar li a.now{ background–color: #fcc; } |
わかりやすく、sectionを色分けして高さをつけています。
サイドメニューは画面上部に固定しています。
jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $(function(){ $(window).on(‘scroll’ , function(){ $(‘.sidebar li a’).each(function() { //変数の作成 var $window = $(window); var $this = $(this); var linkTo = $this.attr(‘href’); //href=””取得 var $target = $(linkTo); var topLimit= $target.offset().top; var bottomLimit = $target.offset().top + $target.outerHeight(); if(topLimit <= $window.scrollTop() && $window.scrollTop() <= bottomLimit){ $this.addClass(‘now’); }else{ $this.removeClass(‘now’); } }); }); }); |
$(window).on(‘scroll’ ,function(){~で、スクロールにより発生するイベントとして書いていきます!
3行目の$(‘.sidebar li a’)が、変化を起こすターゲットです。クラスとかidを指定している場合はそれを書いたほうがいいでしょう。
で、イベント発生ごとに各要素をターゲットとするため、.eachで処理します。
eachは感覚で使ってしまっているので、しっかり勉強せねば…
つぎに、後に使う変数を定義します。
- $window…開いてるウィンドウに対して~するため
- $this…いまターゲットとしている.sidebar li aに対して~するため
- linkTo…$thisを使って、いまターゲットとしている.slidebar li aのhref=””値
- $target…変数linkToをjQueryオブジェクト化。$(linkTo)と書いて代入する
最後の項目はハマってしまいました。linkToをそのまま使いまわすと「TypeError: linkTo.offset is not a function」などとコンソールでエラーが出ます。
以上の変数をベースに、具体的な数値を計算する変数を書きます。このへんです。
1 2 | var topLimit= $target.offset().top; var bottomLimit = $target.offset().top + $target.outerHeight(); |
- topLimit…先ほどの$target(a href=””値、つまりはサイドメニューと対をなすセクション要素)の上端の、HTMLの一番上から$targetの上端の距離。
.offset() | jQuery 1.9 日本語リファレンス | js STUDIO - bottomLimit…$targetの上端の、ページの一番上からの距離 + $targetの高さ = HTMLの一番上から$targetの下端の距離
次のif条件分岐で勝負が決まります…!
1 2 3 4 5 | if(topLimit <= $window.scrollTop() && $window.scrollTop() <= bottomLimit){ $this.addClass(‘now’); }else{ $this.removeClass(‘now’); } |
最初のifは何を言っているかというと、
「ページ上端からスクロールした距離px($window.scrollTop())」が、「ターゲットが対象とするsectionの、ページの上からの位置(topLimit)」よりも大きくて、「ページ上端から、ターゲットのsectionの下端までの距離(bottomLimit)」より小さい
場合に、ターゲットにclass=”now”を付加し、そうでない場合(対象のsectionを通り過ぎた場合)にclass=”now”を外すということです。
で、今回はCSSで
1 2 3 | .sidebar li a.now{ background–color: #fcc; } |
と指定しているので、画面上にhref=””と同じidのsectionが現れた場合、サイドメニューの一部分が赤く背景色が変わる仕様になっています。
デモはこちら。
スクロールして対象要素が現れた時、サイドメニューの色が変わるデモ
あとはCSSの指定で色々アレしてみてください!
今回は.sidebar liにtransitionプロパティを使用しているので、フワッと背景色が変わる感じになってて、ちょっとやわらかくて落ち着いた感じになっていますねー。
この「ある要素が現れたとき、エフェクトを与える」というのは、応用を利かせることにより、非常にクリエイティブな表現ができると思います。
ちょっと違う方法ですが、その応用をしているwebサイトをご紹介します!
jquery.inviewで更にリッチに実装!
jQuery.inviewも似たようなエフェクトを実装できます。
前述の応用を実装するためにはjquery.inviewがお手軽でしょう。
詳しい使い方はこのへんが語ってくださっています。ご参考ください!
スクロールにより、対象のセクションに差し掛かるとこんな感じになるんです。かっこいい!抱かれたい!
BEASHOW (ビショウ) -サロンが開発 本物のサロン品質-
いかがでしたでしょうか。
サイドメニューの色が変わるだけでも、かなりユーザーは迷いにくくなると思います。
今回は「setion1,2…」でしたが、各セクションの見出しを書くことで、より必要な情報を選んで観てもらうことが出来ますね。
意外と単純なコーディングなので是非試してみてくださいー!
でわ!