こんにちは、つばさ(@tsubasa123)です。
現在、サイドバーに何かを追従させるカスタマイズコードを作成中です。
モジュールの追従についてセオリーやベストプラクティスを色々模索していたところ、複数のモジュールに対応したいというニーズを見かけたのでちょっと寄り道してみました。
もし同じようなことでお困りの方がいましたら参考にしていただけるとうれしいです。
確かに正攻法だと大変そう
上記の記事で、しゅう (id:ROUTE53)さんが最下部2つのモジュールを固定したいとコメントを残しているのを偶然見かけまして。このようなことをしているブログはあまり記憶にないのですが、まぁ必要な方には必要な機能なんだなと。
で、シロマティ (id:shiromatakumi)さんもコメントでおっしゃっていますが、2つを固定させることもできそうだけどちょっとめんどくさそう。各要素の高さや要素間の隙間の大きさを計算してそれぞれ指定したりと考えることが増えてしまいます。
コメントの通り、ちゃちゃっとできる感じではないですね。
ならば裏技だ
そのままではめんどくさそうなのですが、ソースコードを追加してもレイアウトやデザインが崩れないという条件を満たすことができれば意外と簡単に実現できたりもします。
裏技と言いましたが、そんな難しいことはしません。固定したい複数の要素を1つの要素で囲んでしまうだけです。1つに囲ってしまえば要素ごとの高さや隙間の大きさを管理する必要がなくなりますので後は簡単です。
jQueryにはwrapAll
という指定した複数の要素を1つの要素で囲むための関数がありますので、これを使うだけで追加のカスタマイズが完了します。
簡単にコードを書いてみました。先の記事のように遅延やレスポンシブ、ウインドウサイズの変更などは考慮していません。あくまで複数の要素を固定するためのサンプルですので細かいところは目をつぶってください。
if ((window.innerWidth ? window.innerWidth: $(window).width()) > 768) { $(window).on('load', function() { $('.hatena-module-search-box, .hatena-module-archive').wrapAll('<div id="fixed-module"></div>'); var $fixedModule = $('#fixed-module'); var $window = $(window); var fixedModuleTop = $fixedModule.offset().top - 20; var fixedModuleWidth = $fixedModule.width(); var isFixed = $fixedModule.css('position') === 'fixed'; setInterval(function() { if ($window.scrollTop() > fixedModuleTop) { if (!isFixed) { isFixed = true; $fixedModule.css({ position: 'fixed', top: '20px', width: fixedModuleWidth, }); } } else { if (isFixed) { isFixed = false; $fixedModule.css({ position: 'relative', top: 0, }); } }; }, 1000 / 100); }); };
こんな感じです。
3行目が2つのモジュールを1つの要素で囲んでいる部分です。この辺をご自身のブログで利用されているカスタマイズに当てはめて、いい感じに変更していただければ複数要素を固定できるようになると思います。
現在私のブログで試験的に導入しています。下二つが「アーカイブ」と「検索」なのでこの2つがスクロールしてもついてきます。まったくのムダ機能、なにこれって感じです。明日には外します。
【2016.12.10追記】
無駄だったので外しました。
さいごに
記事中ではあまり記憶にないと言いましたが、広告とおすすめ記事とかやってるサイトを見落としていただけなのかな、とも思い始めました。そう考えるとアイデア次第ではそれなりに使えるのかもしれません。
コメントでは2つ固定したい、と書かれていたのでサンプルでも2つにしましたが、3つでも4つでも囲ってしまえばいけると思います。高さ足りなくなっちゃうかもしれませんけど。
自己満足ですがスッキリしたのでまたカスタマイズに戻りたいと思います。
ではでは、最後までお付き合いいただきありがとうございました。
コメント