Jao's Blog

プログラミング備忘録

カレンダーを動的に表示する #08

 さて、こちらにおわしますカレンダーですが

f:id:Kyokuya_jao:20200615074536p:plain
 ダミーテキストを表示させているだけなので、実際のカレンダーとは異なります。せめて実際の2020年6月のカレンダーを作れよと思わないこともないです。
 また、それっぽい左右の矢印をクリックしても、何も起きません。なので、各月のカレンダーを動的に表示できるよう、DateTimeクラスを使って改造していきましょう。

完成したものがこちらです

f:id:Kyokuya_jao:20200615213551g:plain
gif変換が上手くいかずチカチカしております
 かの有名な動画教材サイトドットインストールのレッスンそのままなので、カレンダー作成自体に特筆すべき点はありません。
 だがしかし、順風満帆にいかぬのがプログラミングというもの。主に2点の不具合に苦しみました。

不自然な空きスペース

f:id:Kyokuya_jao:20200615074722p:plain
 1日が日曜日な月において、不自然な空きスペースが生まれるという不具合が発生しました。

原因

●空のtr要素が存在する

 カレンダーというものはご存知の如く、1行につき7マス(月〜金)の日付で構成されています。つまり、日曜日で改行しているのです。
 このカレンダーもその例に則り、日曜日になるとtr要素の閉じタグと開始タグ(≒改行)が押し込まれるよう設定されています。

    foreach ($this->_period as $day){
      if($day->format('w') == 0){
        $body .= '</tr><tr>';
      }(以下省略)


 つまり、月の始めが日曜日だと、その直前にtr要素の閉じタグと開始タグが挟まれ、空のtr要素が生じることとなります。その空のtr要素が、不自然な空きスペースを生み出しているのでしょう。

●table要素に高さが設定されている

 table要素の高さは親要素と同等(height: 100%;)となっております。
 試しにtableの高さ要素を消したところ、レイアウトは崩れましたが、空きスペースはなくなりました。

f:id:Kyokuya_jao:20200615074849p:plain
 tr、td要素の高さは、元々設定されておりません。それらの親要素であるtable要素に合わせようとして、空きスペースが生じたということでしょうか。

解決策

●tr要素が空の時、非表示にする

 CSSの:emptyセレクタを用い、trの中身が空だった場合、そのtrを非表示(display: none;)とします。

 しかし、これだけではうまくいきませんでした。:emptyセレクタは、要素の中に空白や改行が存在した時点で無効化されてしまうようです。
 それならばと、jQueryを用い、trの中にtd要素がない場合、空白すらも消し去って完全に空っぽにするようにしましょう。

f:id:Kyokuya_jao:20200615075738p:plain
 この方法により、解決しました。冒頭のtr要素に「firstTr」クラスをつけ、firstTrクラスの中のtd要素の数を計算しています。tdの数が0だった場合、firstTrクラスの中身を跡形もなく消しとばしております。これによって、:emptyセレクタが利くようになりました。

 うまくは行きましたが、少々強引なように思えます。そして、次の方法が最適だと知ることになるのです。

●tr要素に高さを設定する

 原因の項目でも挙げましたが、tableに高さが設定されていることが問題なので
 tableの高さを消し、代わりにtrに高さをつけることで、全てが解決しました。めでたしめでたし。


 さて、カレンダーの動的な生成はこれにて完成しました。

バグはこれだけに非ず……

f:id:Kyokuya_jao:20200615080519p:plain
今日は何日?
 カレンダー上で、当日のマスは薄い黄色で示されるよう設定したのですが  このスクショ撮影日時は2020年6月15日であるにも関わらず、なぜか2020年5月23日になっているのです。
 ローカル環境の問題なのでしょうか……?

 グローバル環境で解決するなら、今の段階では致命的ではないと判断したので、とりあえずは放置しておきます。

 それでは、今回はこのあたりで。