web-dev-qa-db-ja.com

JavaScriptで画像404を検出する

ユーザーがファイルをアップロードした後、画像のサイズ変更やS3へのアップロードなどの追加の処理を行う必要があります。これには最大で10秒かかります。これは明らかにバックグラウンドで行います。ただし、結果ページをすぐにユーザーに表示し、s3の永続的なホームに画像が到着するまでスピナーを表示するだけです。

特定の画像がブラウザ間で正しく読み込まれなかったことを検出する方法を探しています(404)。その場合は、JSを使用してその場所にスピナーを表示し、s3から正常にロードできるまで数秒ごとにイメージをリロードします。

50
Tobias Lütke

From: http://lucassmith.name/2008/11/is-my-image-loaded.html

// First a couple helper functions
function $(id) {
    return !id || id.nodeType === 1 ? id : document.getElementById(id);
}
function isType(o,t) {    return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;}

// Here's the meat and potatoes
function image(src,cfg) {    var img, prop, target;
    cfg = cfg || (isType(src,'o') ? src : {});

    img = $(src);
    if (img) {
        src = cfg.src || img.src;
    } else {
        img = document.createElement('img');
        src = src || cfg.src;
    }

    if (!src) {
        return null;
    }

    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth';
    img.alt = cfg.alt || img.alt;

    // Add the image and insert if requested (must be on DOM to load or
    // pull from cache)
    img.src = src;

    target = $(cfg.target);
    if (target) {
        target.insertBefore(img, $(cfg.insertBefore) || null);
    }

    // Loaded?
    if (img.complete) {
        if (img[prop]) {
            if (isType(cfg.success,'f')) {
                cfg.success.call(img);
            }
        } else {
            if (isType(cfg.failure,'f')) {
                cfg.failure.call(img);
            }
        }
    } else {
        if (isType(cfg.success,'f')) {
            img.onload = cfg.success;
        }
        if (isType(cfg.failure,'f')) {
            img.onerror = cfg.failure;
        }
    }

    return img;
}

そして、ここでそれを使用する方法:

image('imgId',{
    success : function () { alert(this.width); },
    failure : function () { alert('Damn your eyes!'); },
});

image('http://somedomain.com/image/typooed_url.jpg', {
    success : function () {...},
    failure : function () {...},
    target : 'myContainerId',
    insertBefore : 'someChildOfmyContainerId'
});
10
unomi

<img>要素のonerrorイベント。

51
SLaks

最初のオプション:

<img src="picture1.gif" onerror="this.onerror=null;this.src='missing.gif';"/>

2番目のオプション:

<html>
<head>
<script type="text/javascript">
    function ImgError(source){
        source.src = "/noimage.gif";
        source.onerror = "";
        return true;
    }
</script>
</head>
<body>
    <img src="image_example1.jpg" onerror="ImgError(this)" />
</body>
</html>

フィドラーの例

https://jsfiddle.net/dorathoto/8z4Ltzp8/63/

18
Dorathoto

エラーイベントでattrトリガーをバインドするだけです。

$(myimgvar).bind('error',function(ev){
    //error has been thrown
    $(this).attr('src','/path/to/no-artwork-available.jpg');
}).attr('src',urlvar);
9
oasisfleeting

今やりました

if ($('#img')[0].naturalWidth > 0) {

私が気づいたように、画像が404'dの場合、naturalWidthはありませんでした。

ただし、上記の方法を使用したいことは理解できます。

1
Adam Mac

これは私のために働いた(私のものはcoffeescriptにある)。もちろん、代わりにスピナーに置き換える必要があります。

checkImages = ->
  $("img").each ->
    $(this).error ->
      $(this).attr("src", "../default/image.jpg")

$(document).on('page:load', checkImages)

私はJavaScriptの同等物は次のようなものだと推測しています

function checkImages() {
  $("img").each(function() {
    $(this).error(function() {
      $(this).attr("src", "../default/image.jpg");
    });
  });
};

$(document).on( "page:load"、checkImages);

0
dav1dhunt