Skip to content

Instantly share code, notes, and snippets.

@uupaa
Last active September 28, 2022 09:49
Show Gist options
  • Save uupaa/8001551 to your computer and use it in GitHub Desktop.
Save uupaa/8001551 to your computer and use it in GitHub Desktop.
image.onload.error

「ブラウザで画像を先読みしたい、簡単な方法はないか?」と聞かれたら、
(new Image()).src = URL; がお勧めです。

この一行で、ブラウザに画像をキャッシュさせる事ができます。

ただ、ブラウザに任せっきりではなく、細かくハンドリングしたい場合もあります。
このエントリはそのような場合に、どういった情報が利用できるかのメモです。

テストコード

まずはブラウザ毎の挙動を知りましょう。
http://zoo.uupaa.net/issues/image/load.error/ で試せます。

function imageLoader(url) {
  var img = new Image();

  img.onabort = function() { _dump("abort", img); };
  img.onerror = function() { _dump("error", img); };
  img.onload  = function() { _dump("load",  img); };
  img.src = url;
}

function _dump(eventType, img) {
  console.group();
  console.log(eventType === "load" ? "SUCCESS" : "ERROR");
  console.log("img.src = "            + img.src);
  console.log("img.complete = "       + img.complete);
  console.log("img.naturalHeight = "  + img.naturalHeight);
  console.log("img.naturalWidth = "   + img.naturalWidth);
  console.log("img.width = "          + img.width);
  console.log("img.height = "         + img.height);
  console.groupEnd();
}

imageLoader("http://example.com/missing.jpg" + "?t=" + Date.now()); // cache busting
imageLoader("http://gyazo.com/f9e2c42f334f6ce9ce45d5e025602937.png" + "?t=" + Date.now());
imageLoader("http://gyazo.com/f9e2c42f334f6ce9ce45d5e025602937.png");
imageLoader("http://gyazo.com/f9e2c42f334f6ce9ce45d5e025602937.png");

上記のコードを走らせると、 console のような結果になります。

存在しないファイルを読み込んだ場合

存在しないファイル example.com/missing.jpg を読み込んだ場合はこうなります。

Property IE 6,7,8 IE 9,10,11 Chrome Safari Firefox
eventType "error" "error" "error" "error" "error"
complete false false true true true
naturalWidth undefined 0 0 0 0
width 28 28 (IE 11 は 0) 0 0 0
height 30 30 (IE 11 は 0) 0 0 0

width: 28, height: 30 という謎の数字は、IE で画像読み込み失敗時に表示される [×] アイコンのサイズ分です。

存在するファイルを読み込んだ場合

存在するファイル gyazo.com/f9e2c42f334f6ce9ce45d5e025602937.png を読み込んだ場合はこうなります。
IE 6,7,8,9,10 は IE 11 のエミュレーションで確認しています。

Property IE 6,7,8 IE 9,10,11 Chrome Safari Firefox
eventType "load" "load" "load" "load" "load"
complete false (※) true true true true
naturalWidth undefined 1007 1007 1007 1007
width 1007 1007 1007 1007 1007
height 669 669 669 669 669

(iOS, Android の挙動は中の人が暇になった時に追加する予定ですが、基本的にSafariと同じはずです)

※: IE 11 のエミュレーションだと false ですが、 2008年に IE6,7 を実機調査した時は true でした

読み込み完了/失敗をハンドリング

画像の読み込み完了と失敗をハンドリングするには、以下のコードで対応できそうです。

if (img.naturalWidth || eventType === "load") {
  // 読み込み成功
} else {
  // 読み込み失敗
}

シンプルですね。

昔はこのへんの挙動は本当にバラバラでしたが、5年の歳月を経て統一されてきています。 良い感じですね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment