カレンダーを動的に表示する #08
さて、こちらにおわしますカレンダーですが
ダミーテキストを表示させているだけなので、実際のカレンダーとは異なります。せめて実際の2020年6月のカレンダーを作れよと思わないこともないです。
また、それっぽい左右の矢印をクリックしても、何も起きません。なので、各月のカレンダーを動的に表示できるよう、DateTimeクラスを使って改造していきましょう。
完成したものがこちらです
かの有名な動画教材サイトドットインストールのレッスンそのままなので、カレンダー作成自体に特筆すべき点はありません。
だがしかし、順風満帆にいかぬのがプログラミングというもの。主に2点の不具合に苦しみました。
不自然な空きスペース
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の高さ要素を消したところ、レイアウトは崩れましたが、空きスペースはなくなりました。
tr、td要素の高さは、元々設定されておりません。それらの親要素であるtable要素に合わせようとして、空きスペースが生じたということでしょうか。
解決策
●tr要素が空の時、非表示にする
CSSの:emptyセレクタを用い、trの中身が空だった場合、そのtrを非表示(display: none;)とします。
しかし、これだけではうまくいきませんでした。:emptyセレクタは、要素の中に空白や改行が存在した時点で無効化されてしまうようです。
それならばと、jQueryを用い、trの中にtd要素がない場合、空白すらも消し去って完全に空っぽにするようにしましょう。
この方法により、解決しました。冒頭のtr要素に「firstTr」クラスをつけ、firstTrクラスの中のtd要素の数を計算しています。tdの数が0だった場合、firstTrクラスの中身を跡形もなく消しとばしております。これによって、:emptyセレクタが利くようになりました。
うまくは行きましたが、少々強引なように思えます。そして、次の方法が最適だと知ることになるのです。
●tr要素に高さを設定する
原因の項目でも挙げましたが、tableに高さが設定されていることが問題なので
tableの高さを消し、代わりにtrに高さをつけることで、全てが解決しました。めでたしめでたし。
さて、カレンダーの動的な生成はこれにて完成しました。
バグはこれだけに非ず……
カレンダー上で、当日のマスは薄い黄色で示されるよう設定したのですが
このスクショ撮影日時は2020年6月15日であるにも関わらず、なぜか2020年5月23日になっているのです。
ローカル環境の問題なのでしょうか……?
グローバル環境で解決するなら、今の段階では致命的ではないと判断したので、とりあえずは放置しておきます。
それでは、今回はこのあたりで。