「作品クリック拡大できませんよ?」
ギャラリーに並べた絵をクリックすると、暗い背景の上に作品が大きく開く。ライトボックスというやつだ。コードは書いた。動くはずだった。
クリックしても、何も起きない。
まず疑ったのは、上に重なる透明な何か
最初に疑ったのは、画像の上に乗っているオーバーレイだった。
ホバーで作品タイトルを出すために、各作品の上に透明な div を重ねていた。透明でも、要素は要素だ。クリックがそこで止まって、下の画像まで届いていないのではないか。
.gallery-item-overlay に pointer-events:none を足した。これでクリックは透明な層を素通りして、画像に届く。直ったはずだった。
「まだ拡大できませんよ?」
直っていなかった。
原因は、HTMLの順番だった
落ち着いて、JavaScriptが何をしているかを上から追った。
const lbOverlay = document.getElementById('lb-overlay');
lbOverlay.addEventListener('click', ...);
lb-overlay という、拡大表示のための要素を取ってきて、そこにクリックの処理をつける。問題はなさそうに見える。
だが、その <div id="lb-overlay"> を書いた場所が悪かった。私はそれを、<script> よりも後ろに置いていた。
ブラウザはHTMLを上から読む。スクリプトに差しかかった時点で、まだ下にある lb-overlay は生まれていない。getElementById は、存在しない要素を探して null を返す。null に対してクリック処理をつけようとして、そこで全部が止まる。だから、どの作品をクリックしても、何も起きなかった。
透明な層は、犯人ではなかった。順番が犯人だった。
直し方は、移動だけ
修正は一行も書き換えていない。lb-overlay のかたまりを、<script> の前——フッターの直前に移動した。それだけ。
スクリプトが走るとき、要素はもう画面の中にいる。getElementById はちゃんとそれを掴む。クリックが、効くようになった。
pointer-events:none の修正自体は無駄ではなかった。透明な層は、いずれ別の場面で邪魔をしただろう。けれど今回の本当の原因は、見た目でも、CSSでもなく、ただ「どこに書いたか」だった。
動かないとき、人はまず複雑な理由を疑う。重なり。イベントの伝播。ブラウザの癖。けれど答えは、たいてい一番退屈な場所にある。読む順番に、要素が間に合っていたか。それだけのことだった。
次回は、縦と横がばらばらの展示会チラシを、切らずに全部見せた話を書く。
シンプルシステム株式会社 代表 伊藤勝彦