はてなスターを記事ごとではなくて日ごとに付けてもらえるようにした

はてなブログはてなスターは記事ごとに貯まる。記事ごとではなくて、ブログの全体に対してスターを付けられて、次の日にはリセットされているようにしたかった。

はてなブログによって出力されるHTMLをJavaScriptで書き換えることで、はてなスターウィジェットをそのまま利用して実現できた。

はてなブログはてなスターを表示するウィジェットはユーザーが変更できるように提供されてはいない。この記事で説明することははてなブログウィジェットの現在(2023年07月27日)の実装に依存している。今後のはてなブログの変更により動作しなくなる可能性がある。

効果

  • 記事ページのはてなスターを記事へのスターではなく日付ごとのURLに対するスターにする
  • 一覧ページの記事ごとのスターを非表示にする

設置

  • デザイン設定の「記事」ではてなスターのチェックを入れる
  • デザイン設定の「フッタ」に以下のHTMLを追加する
<script>
    (function(){
      // 現在の日本時間でのyyyy-mm-dd文字列
      const today = (new Date(Date.now() + (9 * 60 * 60 * 1000))).toISOString().split("T")[0];

      document.querySelectorAll("[data-hatena-star-container]").forEach(e =>{
          if (e.tagName === 'DIV') {
              e.dataset.hatenaStarUrl = `${location.origin}/#${today}`;
              e.dataset.hatenaStarTitle = `${today}のこんにちは!`;
          } else {
              delete e.dataset.hatenaStarContainer;
          }
        });
    })();
</script>

詳細

はてなブログはてなスターを付けられるウィジェットhttps://s.hatena.ne.jp/js/widget/star.jsスクリプトで実装されている。この star.js は、デザイン設定の「記事」ではてなスターのチェックを入れることで挿入されるようになる。HTMLにはコンテンツと共に data-hatena-star-*** 属性を持った要素(コンテナ要素)が出力される。star.js はコンテナ要素にシャドウDOMを追加してボタンとアイコンを表示する。

star.js は async な script タグで読み込まれて、ウィジェット作成処理は loading が済んだ後で実行される。なので、コンテナ要素の data-hatena-star-*** 属性をloading中に変更してしまえばウィジェットを変更できる。デザイン設定「フッタ」に設定するHTMLはコンテンツの下、フッターの上に出力される。その宣言位置で同期的に実行するJavaScriptを配置すればウィジェット作成処理よりも前に要素の属性を変更できる。

コンテナ要素は、記事ページではDIV要素として出力され、一覧ページではSPAN要素として出力される。DIVかどうかをウィジェットを非表示にするかの判定条件にした。