【jQuery】imgタグのsrcを書き換えて画像を変更する完全ガイド|クリック切り替え・ギャラリー・エラー代替・Ajax対応まで

jQueryで img タグの src 属性を書き換えることで、クリックによる画像切り替え・サムネイルギャラリー・エラー時の代替画像表示などさまざまな画像インタラクションを実装できます。

この記事でわかること

  • attr(“src”)でsrcを変更する基本パターン
  • attr(“src”)とprop(“src”)の違い
  • クリックで画像を切り替える(ボタン・サムネイル)
  • alt属性を画像と同時に変更する
  • 画像読み込みエラー時に代替画像を表示する
  • サムネイルギャラリーで大画像を切り替える実装
  • Ajax/APIで取得した画像URLをimgに設定する
スポンサーリンク

attr(“src”)でsrcを変更する基本

jQueryでimgのsrcを変更するには attr("src", 新しいURL) を使います。

// IDを指定して画像を変更
$('#main-img').attr('src', 'photo-new.jpg');

// クラスを指定して変更(複数のimgに適用される)
$('.product-img').attr('src', 'product-sale.jpg');

// 現在のsrcを取得してから変更する
var currentSrc = $('#main-img').attr('src');
console.log('変更前:', currentSrc);
$('#main-img').attr('src', 'photo-new.jpg');
console.log('変更後:', $('#main-img').attr('src'));
attr(“src”)とprop(“src”)の違い
attr("src") はHTMLに書かれたsrc属性の値(相対URLはそのまま)を取得・設定します。
prop("src") はブラウザが解決した絶対URLを取得のみできます。設定には使いません(propでsrcを設定してもattr同様に動作するブラウザが多いですが、attr を使うのが正しい方法です)。attr()の詳細はattr()完全ガイドを参照してください。

クリックで画像を切り替える

ボタンのクリックに応じて画像を切り替える最も基本的なパターンです。

ボタンクリックで画像を順番に切り替える

<img id="slide-img" src="slide1.jpg" alt="スライド1">
<button id="prev-btn">◀ 前へ</button>
<button id="next-btn">次へ ▶</button>
$(function () {
  var images = [
    { src: 'slide1.jpg', alt: 'スライド1' },
    { src: 'slide2.jpg', alt: 'スライド2' },
    { src: 'slide3.jpg', alt: 'スライド3' }
  ];
  var current = 0;

  function showImage(index) {
    current = (index + images.length) % images.length;  // 範囲外を循環
    $('#slide-img')
      .attr('src', images[current].src)
      .attr('alt', images[current].alt);  // altも同時に変更
  }

  $('#next-btn').on('click', function () { showImage(current + 1); });
  $('#prev-btn').on('click', function () { showImage(current - 1); });
});

data-*属性で切り替え先を管理するパターン

<img id="target-img" src="cat.jpg" alt="猫">
<button class="img-switch-btn" data-src="cat.jpg"  data-alt="猫">猫</button>
<button class="img-switch-btn" data-src="dog.jpg"  data-alt="犬">犬</button>
<button class="img-switch-btn" data-src="bird.jpg" data-alt="鳥">鳥</button>
$(function () {
  $('.img-switch-btn').on('click', function () {
    var $btn = $(this);
    $('#target-img')
      .attr('src', $btn.data('src'))
      .attr('alt', $btn.data('alt'));

    // アクティブボタンのスタイルを切り替える
    $('.img-switch-btn').removeClass('is-active');
    $btn.addClass('is-active');
  });
});

サムネイルギャラリーで大画像を切り替える

商品詳細ページや写真ギャラリーでサムネイルをクリックするとメイン画像が切り替わる実装です。フェード効果も加えます。

<div class="gallery">
  <!-- メイン画像 -->
  <div class="gallery-main">
    <img id="gallery-main-img" src="photo1-large.jpg" alt="写真1">
  </div>
  <!-- サムネイル一覧 -->
  <div class="gallery-thumbs">
    <img class="thumb" src="photo1-thumb.jpg" data-large="photo1-large.jpg" data-alt="写真1" alt="写真1">
    <img class="thumb" src="photo2-thumb.jpg" data-large="photo2-large.jpg" data-alt="写真2" alt="写真2">
    <img class="thumb" src="photo3-thumb.jpg" data-large="photo3-large.jpg" data-alt="写真3" alt="写真3">
  </div>
</div>
$(function () {
  $('.thumb').on('click', function () {
    var $thumb   = $(this);
    var largeSrc = $thumb.data('large');
    var altText  = $thumb.data('alt');
    var $main    = $('#gallery-main-img');

    // フェードアウト → srcを差し替え → フェードイン
    $main.fadeTo(200, 0, function () {
      $(this).attr('src', largeSrc).attr('alt', altText)
             .fadeTo(300, 1);
    });

    // アクティブサムネイルのスタイルを変更
    $('.thumb').removeClass('is-active');
    $thumb.addClass('is-active');
  });
});
fadeTo()でフリッカーなくsrcを差し替える
フェードアウト完了のコールバック内でsrcを変更し、その後フェードインすることで一瞬違う画像が見えるフリッカーを防げます。fadeTo()の詳細はアニメーション完全ガイドを参照してください。

画像読み込みエラー時に代替画像を表示する

画像URLが間違っていたり、画像ファイルが削除されてしまった場合に「画像なし」の代替画像を表示するパターンです。ユーザーにXが表示されるのを防ぎます。

<img class="safe-img" src="may-not-exist.jpg" alt="商品画像">
// 単一の画像のエラーハンドリング
$('#main-img').on('error', function () {
  $(this).attr('src', '/images/no-image.png')
         .attr('alt', '画像を読み込めませんでした');
});

// ページ内の全画像にまとめて設定
$(function () {
  $('img.safe-img').on('error', function () {
    // 無限ループを防ぐ: 代替画像もエラーになった場合は処理しない
    $(this).off('error').attr({
      src: '/images/no-image.png',
      alt: '画像なし'
    });
  });
});
エラーハンドリングの無限ループに注意
エラー時の代替画像自体も読み込めなかった場合、errorイベントが再発火して無限ループになります。$(this).off("error") でハンドラーを解除してから代替画像を設定することで無限ループを防げます。HTMLの onerror="this.onerror=null; this.src='/no-image.png'" でも同様に対処できます。

alt属性を画像と同時に変更する

画像を変更するときは alt属性も同時に更新するのがアクセシビリティのベストプラクティスです。スクリーンリーダーは alt を読み上げるため、srcだけ変えてaltが古いままだとアクセシビリティ上の問題になります。

// 非推奨: srcだけ変えてaltが古いまま
// $('#img').attr('src', 'dog.jpg');  // altはまだ「猫」のまま

// 推奨: srcとaltを同時に変更
$('#img').attr({
  src: 'dog.jpg',
  alt: '犬の写真'
});

// または連鎖
$('#img').attr('src', 'dog.jpg').attr('alt', '犬の写真');
srcsetとsizesも同時に更新する
レスポンシブ画像に srcset を使っている場合は、src を変更しても srcset が残っているとブラウザが srcset を優先します。attr("srcset", "") でsrcsetをクリアするか、srcsetも合わせて設定してください。alt属性の取得・設定についてはimgタグのalt属性を取得するも参照してください。

Ajax/APIで取得した画像URLを設定する

APIから商品情報を取得して画像を動的に表示するパターンです。

$(function () {
  // Ajax完了後にimgのsrcを設定
  $.ajax({
    url: '/api/product/123',
    type: 'GET',
    dataType: 'json',
    success: function (data) {
      // APIレスポンスの画像URLを設定
      $('#product-img').attr({
        src: data.imageUrl,
        alt: data.imageAlt || data.name
      });
    },
    error: function () {
      // 取得失敗時も代替画像を設定
      $('#product-img').attr({
        src: '/images/no-image.png',
        alt: '画像を読み込めませんでした'
      });
    }
  });
});
画像の読み込み完了を待ってから処理する
attr("src") でsrcを変更しても、画像の読み込みは非同期で行われます。「画像が読み込まれたあとに高さを取得したい」などの場合は $(img).on("load", fn) で読み込み完了イベントを使ってください。

方法の比較と使い分け

パターン 主な用途 ポイント
attr(“src”, url)の直接書き換え ボタンクリック・条件分岐 最もシンプル。altも同時に変更する
data-*属性で管理 複数の選択肢から切り替える HTMLを変更するだけでJSは汎用的に使える
fadeTo()でフェードしながら切り替え ギャラリー・商品詳細 フリッカーなしで滑らかに切り替え
error()イベントで代替画像 動的コンテンツ・外部画像 off(“error”)で無限ループ防止が必須
Ajax取得後に設定 APIから画像URLを受け取る場合 成功/失敗両方を処理する

まとめ

jQueryでimgのsrcを変更するには attr("src", URL) が基本です。画像変更時は altも必ず同時に変更してアクセシビリティを保ちましょう。フリッカーを防ぐにはfadeTo()のコールバック内でsrcを変更し、エラーハンドリングには off("error") で無限ループを防ぐのがポイントです。

関連記事: attr()完全ガイド / マウスオーバーで画像を切り替える完全ガイド / imgタグのalt属性を取得する / アニメーション完全ガイド

よくある質問(FAQ)

Qattr(“src”)で変更してもページの画像が変わりません。
Aセレクターが要素を正しく取得できていない可能性があります。console.log($("img#my-id").length) で要素が取得できているか確認してください。また $(function(){...}) 内に書かれているか(DOMが読み込まれる前に実行されていないか)確認してください。動的に追加した要素の場合、追加後にattrを呼ぶ必要があります。
Qsrcを変更したら画像のサイズが崩れました。
A新しい画像のアスペクト比が元の画像と異なる場合、CSSのwidthやheightが指定されていると引き伸ばされることがあります。object-fit: contain をCSSに追加するか、srcと合わせて attr("width", newWidth).attr("height", newHeight) で寸法も更新してください。
Q同じ画像URLを再設定しても画像が再読み込みされません。
Aブラウザのキャッシュが有効なため同じURLの画像はリクエストを送らず再読み込みしません。強制的に再読み込みするには、URLにランダムなクエリパラメーターを付加してください:attr("src", url + "?t=" + Date.now())。ただし、通常の使い方では再読み込みが必要なケースはまれです。
Qsrcsetを使っているimgでsrcを変更しても別の画像が表示されます。
Aブラウザが srcset 属性を優先するため、src を変更してもsrcset に一致する画像が使われることがあります。$(el).attr("srcset", "") でsrcsetをクリアするか、srcsetも合わせて新しい値に更新してください。
Qbackgroundに設定した画像を変更したいです。
Abackground-image を変更する場合はimgタグではなく css() を使います:$("#banner").css("background-image", "url(new-image.jpg)")。または style 属性を直接変更します。img タグと背景画像は目的に応じて使い分けてください。