はてなブログの月間アーカイブをメニューバーにする

はてなブログの月間アーカイブをメニューバーにする

別ブログ「そんなには褒めないよ。映画評」で映画の感想を書いているのですが、まもなく10年ほどになりますので過去記事を見てもらううまい方法はないものかと考え、「月間アーカイブ」をメニューバーにする方法を思い立ちました。

ausnichts.hatenablog.jp

(注)上記リンクは2016/2/24現在、月間アーカイブではなく、50音順メニューになっています。

月間アーカイブは ajax で動的に書きだされている

「月間アーカイブ」の構造を見てみましたら、html で構造だけ書いておいて、データは ajax で動的に書き出しているようです。つまり、

<div id="menubar">
<div class="hatena-module hatena-module-archive" data-archive-type="default" data-archive-url="http://(自分のurl)/archive">
<!-- タイトルは削除
  <div class="hatena-module-title">
    <a href="http://ausnichts.hatenablog.com/archive">月別アーカイブ</a>
  </div>
-->
  <div class="hatena-module-body">
  </div>
</div>
</div>

と、どこにでも書いておけば、自動的にその場所に「月間アーカイブ」を書き出してくれます。

ですので、カスタマイズ > ヘッダ > タイトル下に上のコードを入れて、後は css で整形すればメニューバーになりそうです。その際、指定しやすいように menubar など ID をつけておいたほうがいいでしょう。

で、こうなりました。テーマは公式テーマの Epic です。

「div.hatena-module-body」に年ごと、月ごとリストが挿入されています。

<div class="hatena-module-body">
    <ul class="hatena-urllist">
        <li class="archive-module-year" data-year="2015">
            <div class="archive-module-button">
                <span class="archive-module-hide-button"></span>
                <span class="archive-module-show-button"></span>
            </div>
            <a href="http://(URL)/archive/2015" class="archive-module-year-title">
                2015 (58)
            </a>
            <ul class="archive-module-months">
                <li class="archive-module-month">
                    <a href="http://(URL)/archive/2015/9" class="archive-module-month-title">
                        2015 / 9 (5)
                    </a>
                </li>
                
                <!-- 以下 各月<li></li>繰り返し -->


            </ul>
        </li>
        <li class="archive-module-year archive-module-year-hidden" data-year="2014">
            <!-- 略 -->
        </li>


        <!-- 以下 各年<li></li>繰り返し -->


    </ul>
</div>

最新年のリストを閉じ、表示タイミングをDOM構築後にする

デフォルトでは、最新年の li のみ、クラス「archive-module-year-hidden」を入れずに月ごとリストが開くようになっていますので、javascript でクラスを追加して閉じるようにします。また、このままですと一旦開いたままのリストが表示され、その後閉じることになりますので、div#menubar に直接 style=”display:none” を指定しておき、非表示後に div#menu を表示させます。

<script>
window.onload = function() {
    var menubar = document.getElementById('menubar');
    var years = menubar.getElementsByClassName('archive-module-year');
    years[0].classList.add('archive-module-year-hidden');
    menubar.style.display = 'block';
};
</script>

なお、アーカイブデータは DOM 構築後でないと操作できません。

ああ、そうか。と言いますか、hatenablog.js の関数を呼び出して自分でデータを書き出せばどのタイミングでもできますね、多分。また後日やってみましょう。

記事数削除、アイコン変更、マウスオーバーイベント追加

後は css を書けばいいのですが、せっかく javascript を使いますので、記事数を削除し、アイコンも変更しましょう。また、デフォルトではアイコンをクリックすると月ごとリストが開きますが、これをマウスオーバーでドロップダウンするようにしましょう。出来上がったのが下のコードです。アイコンは はてなブログで使えるアイコンWebフォントの一覧と使い方まとめ – しろかい! さんを参考にさせていただきました。

<script>
window.onload = function() {
    var menubar = document.getElementById('menubar');
    var years = menubar.getElementsByClassName('archive-module-year');
    years[0].classList.add('archive-module-year-hidden');
    for (var i=0,len=years.length; i<len; ++i) {
        years[i].querySelector('.archive-module-hide-button').innerHTML = '<i class="blogicon-chevron-up"></i>';
        years[i].querySelector('.archive-module-show-button').innerHTML = '<i class="blogicon-chevron-down"></i>';
        years[i].querySelector('.archive-module-year-title').innerHTML = years[i].querySelector('.archive-module-year-title').innerHTML.replace(/\s\([0-9]+\)/g, '年');
        years[i].addEventListener('mouseover', function(e) {
            this.classList.remove('archive-module-year-hidden');
        });
        years[i].addEventListener('mouseout', function(e) {
            this.classList.add('archive-module-year-hidden');
        });
    }
    menubar.style.display = 'block';
};
</script>

サンプルCSS

#top-editarea {
  background: #666    ;
  margin: 0 0 60px;
  height: 40px;
}
#menubar .hatena-module {
  margin: 0;
}
#menubar .archive-module-year {
  position: relative;
  display: inline-block;
  border: none;
  padding: 0 10px;
  height: 40px;
  line-height: 40px;
}
#menubar .archive-module-year .archive-module-button {
  float: right;
  font-size: 1.2em;
}
#menubar .archive-module-year > a {
  color: #d91e18;
  font-size: 18px;
  text-decoration: none;
  padding-right: 5px;
}
#menubar .archive-module-year .archive-module-months {
  position: absolute;
  background: #fff;
  border: solid 1px #ddd;
  top: 40px;
  left: 0;
  padding: 0 20px 10px 10px;
  opacity: 1;
  display: block;
  z-index: 1;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
  -ms-transition: all 0.5s;
  -o-transition: all 0.5s;
  transition: all 0.5s;
  max-height: 1000px;
}
#menubar .archive-module-year .archive-module-months li {
  display: block;
  margin: 0;
  padding: 0;
  line-height: 1.8;
  white-space: nowrap;
}
#menubar .archive-module-year .archive-module-months li a {
  color: #454545;
  text-decoration: none;
  font-size: 16px;
}
#menubar .archive-module-year .archive-module-months li:hover a {
  color: #d91e18;
}
#menubar .archive-module-year.archive-module-year-hidden .archive-module-button,
#menubar .archive-module-year.archive-module-year-hidden a {
  opacity: 1;
  color: #fff;
}
#menubar .archive-module-year.archive-module-year-hidden .archive-module-months {
  max-height: 0;
  padding-bottom: 0;
  opacity: 0;
  overflow: hidden;
}
#menubar .archive-module-year .archive-module-hide-button {
  color: #d91e18;
}

出来上がりはこちらです。

実際に稼働させているサイトはこちらです。

ausnichts.hatenablog.jp

(注)上記リンクは2016/2/24現在、月間アーカイブではなく、50音順メニューになっています。