Jquery で一定範囲のみスクロールに追従させてみる。
最近ちょくちょくいろんなサイトで見かける仕掛け。
基本は固定表示で、スクロールすると追従するってやつ。
自分もオシャレの一環として(?)←にあるSNSボタンに適用してみました。
見ての通り、記事が書かれている範囲のみスクロールに追従するようになっております。
当初、やり方はちょちょっと調べればすぐ分かるだろうと余裕こいてたら、紹介されてるのがだいたいスクロールすると無限に追従する系で、一定範囲となるとプラグインを使用したり、追加機能や事細かに指定してたりと「単純かつシンプルに一定範囲だけ追従させたい」自分としてはイマイチあわないということで考えてみました。
もし、このやり方が合うサイトを制作してる方がおりましたら、ご参考ください。
ただし、自分の文才がない+説明ベタな箇所が多数あるので、そこは想像をふくらませてご対応ください。
ここから続き
スクロール追従の基本形。
追従機能の基本は下記を参考にしました。
[jQuery]画面を一定量スクロールした時にサイドバーなどを固定位置に配置する
とてもシンプルでわかりやすいです。ありがとうございます。
ただ、上記のデモページでも確認できるように、この方法だと無限にスクロールに追従してくるので、これに『一定範囲』の制限を追加するようにしました。
offset().bottom もどきでスクロールの終わりを指定。
スクロールする範囲を指定するには、あたりまえですが『スクロールする範囲の上(A地点)』と『スクロールする範囲の下(B地点)』を指定する必要があります。
A地点は上記参考サイトの様に『offset().top』で簡単取得。
そして、B地点も『offset().bottom』で簡単取得できるとおもいきや、こんな関数は無い模様。
なんやてッ。
ちなみに『offset().left』はあっても『offset().right』はありません。
なんやてッ。
そこで、ふと思いついたのが「A地点」と「その要素の高さ」を足せばB地点が割り出せるんじゃね?と。
- Jquery
-
$(.hoge).height() + $(.hoge).offset().top;
でけた。
そんなこんなで完成したコード。
- Jquery
-
$(function(){ // 『変数 sns』に #sns-button(スクロールする要素) を入れる // そのついでに『変数 offset』に offset() を使って『変数 sns』の表示位置を入れる var sns = $("#sns-button") , offset = sns.offset(); // ウィンドウ内でスクロールが発生したら処理スタートッ $(window).scroll(function () { // 『変数 snsBottom』に『変数 sns』の高さと上位置を足した数値を入れる var snsBottom = sns.height() + $(this).scrollTop(); // 『変数 parentBottom』にスクロール範囲の上位置と高さを足した数値を入れる // 今回の場合だと「スクロール範囲 = #sns-button の親要素」なので parent() を使用 var parentBottom = sns.parent().offset().top + sns.parent().height(); // もしウィンドウ内のスクロール上位置が『変数 offset』の上位置より大きかったら // (『変数 offset』より下にスクロールしたら) if($(window).scrollTop() > offset.top) { // もし『変数 parentBottom』の数値が『変数 snsBottom』の数値より小さかったら if(parentBottom < snsBottom){ // 『変数 sns』のcssを変更 sns.css({ "position": "absolute", "top": "auto", "bottom": "0", "left": "0", "margin-left": "0" }); // じゃなかったら } else { sns.css({ "position": "fixed", "top": "0", "left": "auto", "margin-left": "-90px" }); } } else { sns.css({ "position": "absolute", "top": "230px", "left": "0", "margin-left": "0" }); } }); });
自分の場合『#sns-button(id指定)』に対して、CSS ファイルで指定してる関係上、参考サイトの様に class を足すのだと postion:absolute; を操作出来なかったので、CSS を操作するようにしてます。
詳しくはこのブログの style.css の633行目付近と jquery-option.js の38行目付近を見てもらったほうが早いと思います。
あと、『変数 sns』の上位置を取得するのに offset().top じゃなくて scrollTop() なのは、スクロールに追従する関係上、動的に上位置が変更になるためです。
一応、レスポンシブにも対応中。
上記のコードでは省略してますが、jquery-option.js を見ての通り実際にはレスポンシブ用に下記コードが加わります。
- Jquery
-
$(document).ready(function(){ if ( $(window).width() > 641) { ~~~↑のコード~~~ } });
ホントは navigator.userAgent でゴニョゴニョしようとしてたんですが、どぉにも上手くイカなかったのでウィンドウサイズで判定してます。
まぁ、レスポンシブ自体ウィンドウサイズでやってるし。いんだよ。うんうん。
booska☆(2016年8月15日 2:46 PM)
jqueryにとんと詳しくない為、スマホのナビをファーストビューを超えたら下部に固定する方法を
探していたのですが、上部固定はいろいろなサイトで解説があるものの、下部の固定の方法が見つけられず
「offset().bottom」と検索してこちらにたどり着きました。
offset().bottomがないことすらわかってませんでした汗
こちらのコードを参考にし、何とか希望通りの動きにできました。
感謝です。ありがとうございました!
chobir(2016年8月15日 3:34 PM)
booska☆ 様
こんなのでもお役に立てて何よりです。
自分も最初 offset().bottom、.right がないことを知った時は驚きでした…。
サイト制作がんばってくださいッ。