MENU

投稿記事内の画像にlazyloadを適用させてページ読み込みを少しでも早くさせたい、lightboxを使って画像を拡大表示できるようにしてユーザビリティを向上させたい。

そんな時に使えるTipsです。

  • "lazyload" というクラス名を付与する
  • src属性をdata-src属性へ書き換える
  • imgタグをaタグで囲む
  • href属性へ画像パスをセットするのはjsに任せる

というような流れになります。

また、今回は遅延読み込み用スクリプトに「lazysizes」、拡大表示用スクリプトに「Luminous」というプラグインを使用する場合のコードとなっています。
両者ともにjQuery不要で動作する超軽量なスクリプトなので、まだ使ったことがない方は是非使って見てください。使い方はそれぞれ下記の記事にてまとめています。

目次

lazyload手順1:"lazyload" というクラス名を付与する

まずは遅延読み込み用に "lazyload" というクラス名をimgタグへ付与してみます。

the_content()の出力時にクラスを付与する方法

function.phpに追記

function customize_img_attr($content) {
  $re_content = preg_replace('/(<img[^>]*)\s+class="([^"]*)"/', '$1 class="$2 lazyload"', $content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

上記は既存のクラス名を残したまま、クラス名を追加しています。
もしWordPressが自動付与してくるクラス名が不要な場合は、preg_replace()部分を下記のようにすると "lazyload" のみになります。

クラス名を "lazyload" だけにする場合

$re_content = preg_replace('/(<img[^>]*)\s+class="[^"]*"/', '$1 class="lazyload"', $content);

編集中の画像挿入時に追加しておく方法

the_content()の出力時ではなく、編集中のエディタ内に画像を追加した時点でクラスを追加する方法もあります。

function.phpに追記

function remove_image_attr($html){
  $re_html = preg_replace('/class="([^"]+)"/', 'class="$1 lazyload"', $html);
  return $re_html;
}
add_filter('get_image_tag', 'remove_image_attr');

ただし、すでに挿入済みの画像は対処できません。これから始めるブログなどでは非常に有効な方法です。

これもまた、クラス名を1つだけにする場合は下記のように変更してください。

クラス名を "lazyload" だけにする場合

$re_html = preg_replace('/class="[^"]+"/', 'class="lazyload"', $html);

※:挿入済みの画像を編集した場合(代替テキストなど)、クラス名が新たに自動付与されるので注意してください。(lazyloadは残ります)

lazyload手順2:src属性をdata-src属性に書き換える

これは簡単ですね。WordPressでは基本的に一つ目の属性値が srcとなるので、正規表現を使わずとも、 <img src=を書き換えて <img data-src=とするだけです。

src属性をdata-src属性に書き換える(正規表現なし)

function customize_img_attr($content) {
  $re_content = str_replace('<img src=', '<img data-src=', $content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

src属性の前に何か自分で属性値を挿入する可能性がある場合や、アップデートでどうなるかわからないので念のためきっちり正規表現で置換しておきたいという方は下記ようにしましょう。

src属性をdata-src属性に書き換える(正規表現で)

function customize_img_attr($content) {
  $re_content = preg_replace('/(<img[^>]*)\s+src=/', '$1 data-src=', $content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

lazyload手順3:まとめ

手順1・手順2をまとめます。(クラス名をlazyload1つにする方法の例です。)
投稿内の画像全てにlazyloadを適用させたい場合はfunction.phpに以下のコードをコピペしてみてください。

投稿内の画像にlazyloadを適用させるコード

function customize_img_attr($content) {
  $re_content = $content;
  $re_content = preg_replace('/(<img[^>]*)\s+class="[^"]*"/', '$1 class="lazyload"', $re_content);
  $re_content = preg_replace('/(<img[^>]*)\s+src=/', '$1 data-src=', $re_content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

lightbox手順1:imgタグをaタグで囲む

さて、次はlightboxの適用方法についてまとめていきます。

lightboxを適用させるためにまずしなくてはならないことは、imgタグをaタグで囲むことでしょう。

the_content()の出力時にimgタグをaタグで囲むコード

function customize_img_attr($content) {
  $re_content = preg_replace('/(<img[^>]*>)/','<a href="" class="luminous">$1</a>',$content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

上記のコードでは、クラス名は " luminous" 、href属性は にしています。

href属性に表示させたい拡大画像のパスを指定して使うことがほとんだと思うのですが、今回の方法ではこのhref属性の中身はjsで処理しようと思いますので、とりあえず空文字「""」としています。

lightboxを適用させたくない(aタグで囲みたくない)画像がある場合

例えば別サイトへのリンクを画像リンクで設置したい場合など、上記のコードだけではすでにaタグで囲まれている画像もさらにaタグで囲んでしまうことになります。

この回避方法は少し悩みました。「aタグで囲まれていないimgタグにのみマッチさせる」ということが私の正規表現の知識では実現できなかったのです。

そこで、別の案ですが、画像リンクを設置するときは画像タグに「data-nolink」という属性値をセットするというルールを決め、data-nolinkがセットされていない画像タグにのみlightboxを適用させる、という案で私は運用しています。

"data-nolink"という文字列のないimgタグのみaタグで囲むコード

function customize_img_attr($content) {
  $re_content = preg_replace('/(<img\s(?!.*data-nolink)[^>]*>)/','<a href="" class="luminous">$1</a>',$content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

私は内部リンクをショートコードで呼び出しているのですが、ショートコードの呼び出しは上記のコードより後に実行されていて文字列置換の影響を受けずに済んでいるようです。もしショートコードの呼び出し優先度が高くなっていて影響を受けてしまう場合、上記の回避方法でもいいですが、問題がなければショートコードの呼び出しの順序を遅らせてみてください。

lightbox手順2:aタグのhref属性にフルサイズの画像をセット

次いで、lightbox用のクラス名がついたaタグのhref属性に画像パスをセットしていこうと思います。

WordPressの投稿で画像を挿入するときは画像のサイズを指定できるかと思います。これが どのサイズで挿入されていようと、href属性にフルサイズの画像パスをセットする方法を紹介していきます。

WordPressで自動生成される各サイズの画像は、「フルサイズのパス- サイズ.jpg」のようになっています。
例えば画像サイズが600x400サイズとなって挿入される場合、「https://wemo.tech/wp-content/.../image_full-600x400.jpg」のような形になります。

つまり、この「600x400」の部分だけを取り除けばフルサイズの画像パスが取得できるというわけです。

ということで、コードは以下のようになります。

aタグ内のimgタグからフルサイズの画像パスを取得し、href属性へセットする

$(function(){
  $('.luminous').each(function (i, e) {
    var $this = $(e);
    var $thisImg = $this.children('img');
    var imgSrc = $thisImg.attr('src');
    if (imgSrc) {
      var fullSrc = imgSrc.replace(/-[0-9]*x[0-9]*/, "");
      $this.attr('href', fullSrc);
    }
  });
});

上記はlightbox用のクラス名が "luminous" の場合のコードですので、各自のクラス名へ変更してお使いください。

lazyloadと併用する場合、画像のパスは初期状態ではsrcではなくdata-srcに記述されているので、その場合は上記の attr('src')attr('data-src')へと書き換えてください。

lightboxが正常に動作すれば成功です!

まとめ:lazyloadとlightboxを両方使いたい場合のコード

the_contentのフィルターフックに処理をまとめ。lightboxの手順2だけjsで処理します。

PHP側:function.phpに記述

function customize_img_attr($content) {
 $re_content = $content;
  //lazyload用のクラス名を付ける(先に自動付与されている余分なクラス名は除去するパターン)
  $re_content = preg_replace('/(<img[^>]*)\s+class="[^"]*"/', '$1 class="lazyload"', $re_content);
  //src属性をdata-src属性に書き換える
  $re_content = preg_replace('/(<img[^>]*)\s+src=/', '$1 data-src=', $re_content);
  //data-nolink属性を持たないimgタグをaタグで囲む
  $re_content = preg_replace('/(<img\s(?!.*data-nolink)[^>]*>)/','<a href="" class="luminous">$1</a>',$re_content);
  return $re_content;
}
add_filter('the_content','customize_img_attr');

あとはjs側の処理も忘れずに、

JS側のコード

$(function(){
  $('.luminous').each(function (i, e) {
    var $this = $(e);
    var $thisImg = $this.children('img');
    var imgSrc = $thisImg.attr('data-src');
    if (imgSrc) {
      var fullSrc = imgSrc.replace(/-[0-9]*x[0-9]*/, "");
      $this.attr('href', fullSrc);
    }
  });
});

以上です!

正規表現のポイント

今回のTipsで難しいポイントは正規表現部分だと思います。私もすぐに忘れてしまうので、ポイントとなる正規表現だけ、意味をまとめておきます。

  • \s:空白文字
  • .:"\n" を除く任意の 1 文字に一致
  • *:0回以上の繰り返し
  • +:1回以上の繰り返し
  • []:角括弧内の任意の1文字にマッチする
  • [0-9]:0~9の半角数字
  • [^{任意の文字}]:{任意の文字}以外の文字
  • [^>]*>以外の文字が0回以上繰り返している部分
  • "([^"]*)""から"までの中身全部
  • ():括弧内のパターンを1キャプチャとみなし、マッチした部分が順番に$1,$2などに渡される
  • foo(?!hoge):直後に「hoge」という文字列がない場合の「foo」という文字列にマッチ(否定先読み)

おまけ:数字の指定は\dでも良いが、[0-9]の方が効率が良いらしい?

- Thank you for reading this to the end. -
TOPへ Top