『7回目の出直し🌻』

好きなことを自分のペースで、のんびり更新

記事ページの右側が寂しかったので、ぴたっと固定できるコンテンツを置いてみた

無いなら作ろうシリーズ 第6弾

記事ページを下にスクロールすると、サイドバーにコンテンツがなくなっちゃうので、右下のほうが真っ白で寂しいですね。 はてなブログのサイドバーにコンテンツを固定するのをやってみたので紹介します!let's sticky!

困っていること

スクショ付きの記事を作るとどうしても縦長の記事ページになります。下のほうにスクロールしていくとサイドバーのコンテンツがなくなり、画面が寂しい感じになります。 f:id:kanaxx43:20200703002733p:plain

このさみしさを解消するために、ちょっとしたプログラムを作ってみました。 過去にCSSだけでStickyする方法も試したのですが、テーマとの相性もあるのか、あまり上手くいかなかったので、自作することにしました。

作ったもの

完成品のイメージは、こんな感じです。

埋め込むコンテンツは、自分で好きなようにHTMLを作れるようにしてあります。
条件が揃ったときだけ、H3レベルだけの目次を自動で生成するようにしています。
f:id:kanaxx43:20200628153102p:plain

使ったもの

  • Javascript
  • jQuery(はてなブログで使ってるデフォルトのバージョン)

ブログテーマはCONTENTSを使わせてもらっています。 このテーマはレスポンシブなテーマなので、PCでもスマホでも同じように見えます。

ソースコード

今回のソースコードは、HTML部分とJavascript部分が混在して70行程度です。

HTMLの部分

15行目の<!-- HTMLのコンテンツ ここまで-->までは、追従するコンテンツをHTMLを書く部分です。僕の場合は10行くらいですが、何行になっても大丈夫です。好きに変えてもよいです。

<!-- HTMLのコンテンツ -->
<span style="font-size: 125%;"><span class="markb">読者登録お願いします!</span></span><br>

<i class="far fa-hand-point-right fa-2x faa-horizontal animated"></i> <iframe
  src="https://blog.hatena.ne.jp/kanaxx43/kanaxx.hatenablog.jp/subscribe/iframe" allowtransparency="true"
  frameborder="0" scrolling="no" width="150" height="28"></iframe>

<ul class="sidebar-mokuji"></ul>

<br>
<iframe
  src="https://rcm-fe.amazon-adsystem.com/e/cm?o=9&p=12&l=ur1&category=home_r&f=ifr&linkID=0f0ad5300484f8cc0c8fa9fa81ea5808&t=kanaxx-22&tracking_id=kanaxx-22"
  width="300" height="250" scrolling="no" border="0" marginwidth="0" style="border:none;" frameborder="0"></iframe>

<!-- HTMLのコンテンツ ここまで-->

<script>
  class HatenaSidebar {
    initOffsetTop = null;
    boxSelector = 'div.hatena-module:last';
    showStar = false;
    yobiHeight = 200;
    stickyTopMargin = 15;
    box = null;

    constructor(selector) {
      this.boxSelector = selector;
      this.box = $(this.boxSelector);
      this.initOffsetTop = this.box.offset().top + this.yobiHeight;
      this.createMokuji();
    }

    createMokuji() {
      if ($('ul.sidebar-mokuji').length > 0) {
        var midashi = $('h3');
        if (midashi.length > 0) {
          midashi.each(function (i, e) {
            let txt = $(e).text();
            e.id = txt;
            $('ul.sidebar-mokuji').append(`<li><a href="#${txt}">${txt}</a></li>`);
          });
          $('ul.sidebar-mokuji').addClass('table-of-contents');
        }
      }
    }

    scrollbox() {
      if (this.initOffsetTop == null) return;

      let scrollTop = $(document).scrollTop();

      if (this.initOffsetTop < scrollTop) {
        this.box.css('position', 'fixed');
        this.box.css('top', this.stickyTopMargin);
      } else {
        this.box.css('position', 'relative');
      }
    }

    isSmartPhone() {
      if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
        return true;
      } else {
        return false;
      }
    }
  }

  hatenaSidebar = new HatenaSidebar('div.hatena-module:last');
  if (!hatenaSidebar.isSmartPhone()) {
    $(window).scroll(function () {
      hatenaSidebar.scrollbox();
    });
  }
</script>
目次を付ける場合

<ul class="sidebar-mokuji"></ul>を置いておくと、記事内からH3タグを自動で探して目次を作ります。はてなブログの標準目次スタイルであるtable-of-contentsを使いますので、見た目のカスタマイズは可能です。

サイドに固定するコンテンツに目次が要らない場合は、このタグを置かなければよいです。

固定位置の調整

stickyTopMargin = 15;
この変数を大きくすると、固定パーツが下に下がります。いい感じに調整してください。

予備の縦幅

yobiHeight = 200;
実際にスクロールすると微妙に重なってしまう場合、この数値を大きめにすると改善する可能性があります。 サイドバーの中には、画面を表示してから作られるものがあり、その部分の膨らみを正確に計算せずにだいたい200pxくらいだろうとやっているためです。人によって膨らみ方が違うので調整が必要かもしれません。

設置&実行

ソースコードをコピーして、デザインメニューのサイドバー、HTMLモジュールに貼り付けます。 サイドバーの一番最後のパーツに移動してください。移動しないと別のパーツが固定されると思います。

※デザインのプレビューページでは、jQueryが読み込めずにうまく動かないかもしれません。デザインをいったん保存して記事ページを確認してみてください

実行

サイドバーを保存して、記事ページを開き、上下にスクロールしてみてください。

こんな感じに動けば、完成です。

まとめ

今回は右側にできがちなサイドバーの空きスペースを有効に活用する方法でした。これで、下スクロールしても先細りして寂しい感じがなくなりましたね。
そんなに難しくないと思うので、使ってみてください。

参考資料

追いかけてくるフローティングボックスを作る
https://qiita.com/katsukii/items/d3b7c55a3e95909b7f4c