「画像クリックで拡大表示したい」
クライアントからのこの一言、Web屋なら年に3回は聞くやつです。そして脳内で天使と悪魔が会議を始めます。
- 天使「Lightboxプラグイン入れれば5分で終わるよ」
- 悪魔「そのプラグイン、3年後に更新止まってPHP警告吐くぞ」
今回は悪魔の忠告に従い、外部ライブラリゼロ・jQuery非依存・コピペ1発のモーダル表示を素のJavaScriptで実装します。10年物の化石テーマで実際に動かした実績付きです。
この記事でできること
- 投稿内の画像をクリック → 画面いっぱいにフワッと拡大
- どこをタップしても閉じる(スマホ対応)
- サムネイルじゃなくフルサイズの元画像を表示
- プラグイン追加ゼロ、jQueryなし、依存ゼロ
なぜプラグインを使わないのか
Lightbox系プラグインは山ほどあります。それでも今回コードで済ませる理由は3つ。
- プラグインは増えるほど遅く、壊れやすくなる。モーダル1個のために管理画面の住人を増やすのは、醤油を借りるために同居人を増やすようなものです
- 古いテーマだと同梱のjQueryが化石(1.x系とか)で、プラグインが要求するバージョンと普通に喧嘩します
- 更新が止まったプラグインは、将来のセキュリティ警告製造機になります
コピペ20行で済むものは、コピペ20行で済ませましょう。
コード全文
以下をコピーしてください。設置場所は後述します。
<script>
(function(){
// ▼ 拡大表示用のオーバーレイを1個だけ作っておく
var overlay = document.createElement('div');
overlay.id = 'imgModal';
overlay.style.cssText = 'display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:99999;background:rgba(0,0,0,.85);justify-content:center;align-items:center;cursor:zoom-out;';
var big = document.createElement('img');
big.style.cssText = 'max-width:95vw;max-height:95vh;';
overlay.appendChild(big);
document.body.appendChild(overlay);
// ▼ 投稿画像にだけ「拡大できるよ」カーソルを付ける
var css = document.createElement('style');
css.textContent = 'img[src*="/wp-content/uploads/"]{cursor:zoom-in}';
document.head.appendChild(css);
// ▼ クリックを1箇所で監視(画像が後から増えても動く)
document.addEventListener('click', function(e){
var t = e.target;
// モーダル表示中のクリックは「閉じる」
if (t.closest && t.closest('#imgModal')) {
overlay.style.display = 'none';
return;
}
// アップロード画像だけを対象にする
if (t.tagName === 'IMG' && t.src.indexOf('/wp-content/uploads/') !== -1) {
// 元画像が消されてたらサムネイルで我慢するフォールバック
big.onerror = function(){ this.onerror = null; this.src = t.src; };
// 「-1024x768.jpg」→「.jpg」に変換してフルサイズを表示
big.src = t.src.replace(/-\d+x\d+(\.\w+)$/, '$1');
overlay.style.display = 'flex';
}
});
})();
</script>
以上です。ライブラリの読み込みタグ? ありません。それがこの記事の存在意義です。
コードのポイント解説
/wp-content/uploads/ で対象を絞る
サイト内の全画像を拡大対象にすると、ヘッダーロゴをタップした人が突然フルスクリーンのロゴと対面する事故が起きます。誰も得しません。src にアップロードディレクトリを含む画像、つまり投稿にアップロードされた画像だけに反応させています。
もっと絞りたい場合は、条件を t.closest('.post') などで記事エリア内に限定してください。
-1024x768.jpg を剥がしてフルサイズを出す
ここが地味に一番いい仕事をします。WordPressは画像をアップロードすると、写真.jpg から 写真-1024x768.jpg のような縮小版を自動生成し、投稿にはたいてい縮小版が貼られます。
せっかくモーダルで大きく表示するのに中身がサムネイルだったら、拡大したのにボヤけるという「近視のまま双眼鏡を覗く」状態になります。そこで正規表現 -\d+x\d+(\.\w+)$ でサイズ表記を削り、オリジナル画像のURLに変換してから表示しています。
元画像が存在しない場合の保険
メディア設定によっては元画像が削除されていてフルサイズURLが404になることがあります。その場合は onerror でサムネイルにフォールバックするので、真っ黒画面で読者が置き去りになることはありません。
イベントは document で1箇所監視
各画像に個別にイベントを付けるのではなく、クリックを document で一括監視しています(イベント委譲というやつです)。これにより、後から追加された画像や遅延読み込みの画像でもそのまま動きます。手間を減らした結果として堅牢になる、エンジニア人生でも稀に見るwin-winです。
設置場所は3択
| 方法 | 手軽さ | テーマ更新で消えない |
|---|---|---|
① footer.php の </body> 直前 |
◎ | ✕(親テーマ直編集の場合) |
| ② ヘッダー/フッター挿入系プラグイン | ○ | ◎ |
| ③ 子テーマの footer.php | △ | ◎ |
手っ取り早いのは①ですが、親テーマを直接編集していると、テーマ更新の日にコードが静かに消滅します。しかも誰も気づかない。半年後に「拡大できなくなってるんですけど」という連絡で発覚します(実話がありそうな話)。
長く運用するサイトなら、②の「WPCode」等の挿入プラグインか、③の子テーマ運用が安全です。「プラグインなしと言ったな、あれは表示機能の話だ」ということでご容赦ください。挿入プラグインは中身がただの器なので、Lightboxプラグイン本体を飼うのとはリスクの桁が違います。
動作確認
- 設置後、投稿ページを開く
- 記事内の画像にマウスを乗せる → カーソルが虫眼鏡(zoom-in)になればJSは生きてます
- クリック → 黒背景で画像がドンと拡大
- どこでもいいのでタップ → 閉じる
カーソルが変わらない場合はブラウザのキャッシュを疑ってスーパーリロード(Ctrl+Shift+R)を。それでもダメならF12のコンソールにエラーが出ていないか確認してください。だいたいコピペ時にタグが欠けています。人類はコピペを完遂できない生き物です。
まとめ
- Lightbox系の表示はバニラJS 約20行で自前実装できる
/wp-content/uploads/判定で投稿画像だけを対象化- サイズ表記の除去でフルサイズ表示、404時はサムネにフォールバック
- 親テーマ直編集は更新で消えるので、挿入プラグインか子テーマ推奨
プラグインを1個入れる前に「それ、20行で書けへんか?」と自問する習慣、サイトの寿命を確実に延ばします。それでは良きコピペライフを。
