Blogger:カレンダー(12)Calendar5_Bloggerモジュールの導入

Calendar4_Bloggerモジュールコードが読みにくかったので整理しました。ついでにアイテムページを開いた時に、その投稿の日付の投稿リストを展開して、アイテムページに表示している投稿をハイライトするようにしました。

前の関連記事:Blogger:カレンダー(11)祝日対応などCalendar4_Bloggerモジュール


Calendar5_Bloggerモジュールの設置方法


Calendar5_Blogger/Calendar5_Blogger.js at 83cf7ea9ebe73ad4f2bf61119ffc04a9bb94244f · p--q/Calendar5_Blogger

これまでと同じくレイアウト画面でHTML/JavaScriptガジェットに入れて配置するだけです。

置換するdiv要素のidはデフォルトではcalendar5_bloggerにしています。

なので、このモジュールの配置の前に<div id="calendar5_blogger"></div>をおいておけばそこにカレンダーが入ります。
Calendar5_Blogger.defaults["StartYear"] = 2013; // 遡る最大年。
Calendar5_Blogger.defaults["StartMonth"] = 3; //  遡る最大月。
Calendar5_Blogger.all("calendar5_blogger");  // idがcalendar5_bloggerの要素にカレンダーを表示させる。
StartYear年StartMonth月まで遡るとそれ以上遡る矢印が表示されなくなります。

表示される最新の月は現在の月までです。

祝日については休日のJSONの作成ツール、日数計算ツールで作成したJSONデータを169行目に代入しています。

コーディングにあたって調べたこと


Git(24)EclipseでGit Flowを使う:その2で導入したGit Flowを使うとコミットをたどればよいので、コーディングのステップをいちいちブログに記録する必要がなくなりました。

ブランチが思う通りにマージできないことがあるのが問題ですけど、、、

Calendar5_Bloggerモジュールを作成するにあたって調べて学習したことを記録しておきます。

HTML5 カスタムデータ属性「data-*」にJavaScript、jQueryからアクセスする方法 - ROCHAS

曜日の情報を日付のdiv要素に持たせるために、これまではプロパティを勝手に作って7との剰余を代入していましたが、Node.cloneNodeでノードを複製するとそのプロパティが複製されませんでした。

data-を接頭語につけると消えることなく複製されました。

なので、176行目でdata-remainderというプロパティを作ってそこに曜日情報をもたせました。

forループとforEach内でreturnした時の挙動の違い - Qiita

270行目で、ループを途中でreturnで抜けたかったのですが、forEachではスマートな方法はないようです。

forは文、forEachはメソッドという違いのようです。

ということでreturnでループを抜けれるfor文を採用しました。

[CSS]CSSの pointer-events で <a> タグのリンクを無効化する方法

アイテムページでは表示している投稿について投稿リストをハイライトするようにしたのですが、タイトルをクリックしても反応しないようにするのに、262行目でpointer-events:noneをスタイルに設定しました。

このスタイルを設定するだけでデザインを変えることなくaタグのリンクに反応しなくできました。

月を切り替える矢印を連打するとJSONで取得したデータと月がずれる


例えばカレンダーの右上にある前の月に移動する矢印ボタンを連打すると、2013年3月を乗り越えて2013年2月までカレンダーが表示され、投稿のある日のハイライトが2016年3月になっているという奇妙なことが起こりました。

この解決にはとても時間がかかりました。

矢印をゆっくりクリックすると問題は発生しないので、コールバック関数がフィードが来るのを待っている間に次の月のカレンダーを作成するのが問題と考えました。

【Promise】JSONPの読み込みをThenableにする - Qiita

ECMAScript6を使ってみた ~「Promise」編 | DACエンジニアブログ:アドテクゑびす界

これらを参考にしてまずJSONPでフィードのデータが返ってくるのをPromiseで待たすことを考えました(jQuery.Deferred学習メモ(1)$.DeferredでPromiseを操作する参照)。

しかしそもそもJSONPというのがフィードのデータの到着を待ってコールバック関数にデータを渡すものですから、一つのフィードの結果を待つだけならPromiseを使う意味はないことがわかりました(Blogger:JSONPを使ってJSON形式でブログの情報を引き出す参照。)

次に考えた方法は、同じ名前のコールバック関数でフィードデータを受け取るので、月がずれていくのだと考えて、コールバック関数名をランダム化してコールバック関数名が重ならないようにしてみました。

しかしこれもまた問題は解決しませんでした。

予測した問題点が外れたので途方にくれましたが、苦肉の策として先ほど使ったpointer-events:noneで、矢印をクリックしたらまず矢印ボタンへのクリックが無効になるようにしました(323行目と328行目)。

それが正解でした、、、結構悩みましたのに、この簡単な設定で問題が全く発生しなくなりました。

(2017.3.11追記
Calendar5_Blogger/Calendar5_Blogger.js at b92d7a3af499992d72b07e69f28f8a9ae2c4df26 · p--q/Calendar5_Blogger
コメントリストからアイテムページに飛んだ時などアイテムページのURLの後ろにパラメーターが付いているとカレンダー下の投稿リストがハイライトされない問題を修正しました。)

Calendar5_Blogger/Calendar5_Blogger.js at develop · p--q/Calendar5_Blogger

しばらくはこのdevelopブランチを更新していくことにします。

Git Flowのmasterブランチの使い方がよくわからないので、、、

pointer-events:noneのせいか、何回かクリックしているとカレンダーのクリックだけ無効になってしまったので、pointer-events:noneはなるべく限定的に使うようにしました。

更新日の投稿についてハイライトがうまくできていなかったのも修正しました。

参考にしたサイト


HTML5 カスタムデータ属性「data-*」にJavaScript、jQueryからアクセスする方法 - ROCHAS
data-を接頭語にしたプロパティはNode.cloneNodeでも複製されました。

forループとforEach内でreturnした時の挙動の違い - Qiita
forEachメソッドは途中で抜けることはできずfor文ではreturnではループを途中で抜けれます。

[CSS]CSSの pointer-events で <a> タグのリンクを無効化する方法
pointer-events:noneをスタイルに設定すると、aタグだけでなくイベントハンドラの発火も無効にできました。

【Promise】JSONPの読み込みをThenableにする - Qiita
フィードをJSONPで複数揃うのを待つ例。

ECMAScript6を使ってみた ~「Promise」編 | DACエンジニアブログ:アドテクゑびす界
Promiseを使わずに同等のことをする例があり、Promiseの働きがよくわかります。
PR

2 件のコメント:

  1. こんにちは。先日からこちらのカレンダーを使わせて頂いております。
    さて、一点、バグらしきものに気づきましたので報告させていただきます。
    同じ年月内にてカスタムURLの末尾の文字列が同じ記事が存在する場合、カレンダーの下のハイライトが当該記事以外になってしまうようです。
    具体的な条件はURLに"-"(ハイフン)が含まれていて、それ以降の文字列が同じ場合に起こります。
    例えば
    http://exsample.blogspot.jp/2017/07/123-abc.html のページで
    http://exsample.blogspot.jp/2017/07/456-abc.html がハイライト表示される。
    ハイフンが含まれないとこの現象は起こらないようです。
    今のところ当方のメインのブログで当該記事はなく、テスト用ブログの方で発覚したため弊害は無いのですが、お手隙の時にでも修正していただければ幸いです。
    よろしくお願いいたします。

    返信削除
    返信
    1. ご指摘ありがとうございます。
      おそらく正規表現パターンに問題があると思います。
      いまLibreOfficeのPythonにとっかかりですので、それが一段落したらまたJavaScript脳に切り替えて、書き換えようと思っています。

      削除