检测何时无法在Javascript中加载图像

时间:2012-03-22 02:50:43

标签: javascript image-loading imagesource onerror

有没有办法确定图像路径是否会导致实际图像,即检测到图像无法在Javascript中加载。

对于Web应用程序,我正在解析xml文件并从图像路径列表中动态创建HTML图像。服务器上可能不再存在某些图像路径,因此我希望通过检测哪些图像无法加载并删除该HTML img元素来优雅地失败。

注意JQuery解决方案无法使用(老板不想使用JQuery,是的,我知道不要让我开始)。我知道JQuery中有一种方法可以检测图像何时加载,但不知道它是否失败。

我的代码用于创建img元素但是如何检测img路径是否导致无法加载图像?

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

8 个答案:

答案 0 :(得分:90)

您可以尝试以下代码。我不能担保浏览器兼容性,所以你必须测试它。

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抗拒老板的同情!

答案 1 :(得分:32)

答案很好,但它引入了一个问题。只要您直接指定onloadonerror,它就可以替换之前分配的回调。这就是为什么有一个很好的方法,“在MDN上对他们在上调用的EventTarget上注册指定的监听器。您可以在同一事件中注册任意数量的侦听器。

让我稍微改写一下答案。

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");

因为外部资源加载过程是异步的,所以使用具有promise的现代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');
    }

);

答案 2 :(得分:13)

此:

<img onerror="this.src='/images/image.png'" src="...">

答案 3 :(得分:4)

/**
 * 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 :(得分:3)

这是我为另一个答案写的函数:Javascript Image Url Verify。我不知道它是否正是您所需要的,但它使用了您将使用的各种技术,其中包括onloadonerroronabort和一般超时的处理程序。

由于图像加载是异步的,因此您可以使用图像调用此函数,然后稍后使用结果调用回调。

答案 5 :(得分:3)

jQuery + CSS for img

使用jQuery这对我有用:

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

我可以在我的网站上随处使用这张图片,无论其大小如何,具有以下CSS3属性:

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

提示1:使用至少800 x 800像素的方形图像

     

提示2:与人物肖像一起使用时,请使用object-position: 20% 50%;

CSS仅适用于background-img

对于缺少背景图片,我还在每个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]

答案 6 :(得分:0)

这是@emil.c 答案的变体,但根据图像加载与否使用真/假解决(而不是在失败时抛出错误):

function testImage(url) {
  if (!url || typeof url !== 'string') return Promise.resolve(false);
  return new Promise((resolve) => {
    const imgElement = new Image();
    imgElement.addEventListener('load', () => resolve(true));
    imgElement.addEventListener('error', () => resolve(false));
    imgElement.src = url;
  });
}

答案 7 :(得分:-17)

如下所示:

var img = new Image(); 
img.src = imgUrl; 

if (!img.complete) {

//has picture
}
else //not{ 

}