web-dev-qa-db-ja.com

画像がJavascriptで読み込めない場合を検出する

画像パスが実際の画像につながるかどうかを判断する方法はありますか。つまり、画像がJavascriptでロードに失敗したことを検出します。

Webアプリの場合、xmlファイルを解析し、画像パスのリストからHTML画像を動的に作成しています。一部の画像パスはサーバー上に存在しない可能性があるため、どの画像がロードに失敗したかを検出し、そのHTML img要素を削除することにより、正常に失敗したいと思います。

注:JQueryソリューションを使用することはできません(上司はJQueryを使用したくないため、始めてください)。 JQueryでイメージが読み込まれたときを検出する方法を知っていますが、失敗したかどうかはわかりません。

Img要素を作成するコードですが、imgパスが画像の読み込みに失敗したかどうかを検出するにはどうすればよいですか?

var imgObj = new Image();  // document.createElement("img");
imgObj.src = src;
83
sazr

次のコードを試すことができます。ただし、ブラウザの互換性を保証することはできませんので、テストする必要があります。

function testImage(URL) {
    var tester=new Image();
    tester.onload=imageFound;
    tester.onerror=imageNotFound;
    tester.src=URL;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

そして、jQueryに耐性のあるボスに対する私の同情!

93
Nikhil

答えはニースですが、1つの問題があります。 onloadまたはonerrorを直接割り当てるたびに、以前に割り当てられたコールバックが置き換えられる場合があります。 "onと呼ばれるEventTargetで指定されたリスナーを登録する"のNiceメソッドがあるのはそのためです MDN 。同じイベントに必要なだけリスナーを登録できます。

答えを少し書き換えてみましょう。

function testImage(url) {
    var tester = new Image();
    tester.addEventListener('load', imageFound);
    tester.addEventListener('error', imageNotFound);
    tester.src = url;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

外部リソースの読み込みプロセスは非同期であるため、次のような約束を備えた最新のJavaScriptを使用するとさらに便利です。

function testImage(url) {

    // Define the promise
    const imgPromise = new Promise(function imgPromise(resolve, reject) {

        // Create the image
        const imgElement = new Image();

        // When image is loaded, resolve the promise
        imgElement.addEventListener('load', function imgOnLoad() {
            resolve(this);
        });

        // When there's an error during load, reject the promise
        imgElement.addEventListener('error', function imgOnError() {
            reject();
        })

        // Assign URL
        imgElement.src = url;

    });

    return imgPromise;
}

testImage("http://foo.com/bar.jpg").then(

    function fulfilled(img) {
        console.log('That image is found and loaded', img);
    },

    function rejected() {
        console.log('That image was not found');
    }

);
35
emil.c

この:

<img onerror="this.src='/images/image.png'" src="...">
17
Rafael Martins
/**
 * Tests image load.
 * @param {String} url
 * @returns {Promise}
 */
function testImageUrl(url) {
  return new Promise(function(resolve, reject) {
    var image = new Image();
    image.addEventListener('load', resolve);
    image.addEventListener('error', reject);
    image.src = url;
  });
}

return testImageUrl(imageUrl).then(function imageLoaded(e) {
  return imageUrl;
})
.catch(function imageFailed(e) {
  return defaultImageUrl;
});
4
holmberd

jQuery + CSS for img

JQueryを使用すると、これは私のために働いています:

$('img').error(function() {
    $(this).attr('src', '/no-img.png').addClass('no-img');
});

また、次のCSS3プロパティを使用して、サイズに関係なく、この画像をWebサイトのどこでも使用できます。

img.no-img {
    object-fit: cover;
    object-position: 50% 50%;
}

ヒント1:少なくとも800 x 800ピクセルの正方形の画像を使用します。

ヒント2:人々の肖像で使用するには、object-position: 20% 50%;を使用します

Background-imgのみのCSS

背景画像が欠落している場合、各background-image宣言に以下を追加しました。

background-image: url('path-to-image.png'), url('no-img.png');

注:透明な画像では機能しません。

Apacheサーバー側

別の解決策は、ブラウザに送信する前にApacheで欠落している画像を検出し、デフォルトのno-img.pngコンテンツで置き換えることです。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} /images/.*\.(gif|jpg|jpeg|png)$
RewriteRule .* /images/no-img.png [L,R=307]
3
Meloman

ここに別の答えのために書いた関数があります: Javascript Image Url Verify 。必要なものかどうかはわかりませんが、onloadonerroronabortおよび一般的なタイムアウトのハンドラーを含む、使用するさまざまな手法を使用します。

画像の読み込みは非同期であるため、画像を使用してこの関数を呼び出し、その後、結果とともにコールバックを呼び出します。

3
jfriend00