HTMLのimg
タグにおけるsrcsetといえばデバイス毎にいい感じに指定した画像を取得してくれる仕組みですが、これをonerrorでハンドリングした際のハマリポイントを書き残しておきます。
onerrorでハンドリング
img
タグの画像がうまく読み込めなかった場合に別の画像に差し替える手法としてonerror
が利用できます。
<img src="/path/src.jpg" alt="image" onerror="this.src='/path/error-src.jpg'" />
src="/path/src.jpg"
が読み込み失敗した場合にonerror="this.src='/path/error-src.jpg'"
onerrorが実行され、javascriptによりthis.src
が上書きされます。
srcset利用時に上記設定で読み込みループになる
上記のパターンにsrcset
を追加してみます。
<img
src="/path/src.jpg" srcsert="/path/src.jpg 1x, /path/src@2.jpg x2"
alt="image"
onerror="this.src='/path/error-src.jpg'"
/>
この場合srcset
に指定している画像が読み込めなかった場合に読み込みループが発生します。(Chromeで事象を確認)
どういうことかというと、
-
src
にsrcset
によるデバイス別のURLが指定されて読み込みが開始される - 1の画像が読み込めなかった場合に
onerror
が呼ばれ、src
が上書きされる - 2で
src
が上書きされたことでブラウザは再度画像を読み込む - 1に戻る
といったような挙動が見られました。(実際の処理は違うかもしれません)
ということで改善方法
読み込みループを回避
<img
src="/path/src.jpg" srcsert="/path/src.jpg 1x, /path/src@2.jpg x2"
alt="image"
onerror="this.src='/path/error-src.jpg';this.srcset='/path/error-src.jpg'"
/>
onerror
時にsrc
だけでなくsrcset
の値も変更します。これで先程の4に当てはまった場合に書き換わったsrcset
が利用されるので無事エラー時の画像に切り替わります。
なんてことないですね