我有一个网页,里面有很多图片。有时映像不可用,因此在客户机的浏览器中显示一个损坏的映像。

我如何使用jQuery来获取图像集,过滤它到破碎的图像,然后替换src?


—我本以为用jQuery会更容易做到这一点,但事实证明使用纯JavaScript解决方案更容易,也就是Prestaul提供的解决方案。


当前回答

这是一个快速和肮脏的方法来替换所有破碎的图像,没有必要改变HTML代码;)

codepen例子

    $("img").each(function(){
        var img = $(this);
        var image = new Image();
        image.src = $(img).attr("src");
        var no_image = "https://dummyimage.com/100x100/7080b5/000000&text=No+image";
        if (image.naturalWidth == 0 || image.readyState == 'uninitialized'){
            $(img).unbind("error").attr("src", no_image).css({
                height: $(img).css("height"),
                width: $(img).css("width"),
            });
        }
  });

其他回答

CoffeeScript变体:

我这样做是为了修复Turbolinks的一个问题,该问题有时会导致.error()方法在Firefox中被引发,即使图像确实存在。

$("img").error ->
  e = $(@).get 0
  $(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)

我不确定是否有更好的方法,但我可以想到一个hack来获得它-你可以Ajax post到img URL,并解析响应,看看图像是否真的回来了。如果返回404或其他错误,则更换img。不过我估计过程会很缓慢。

我认为我有一个更优雅的方式与事件委托和事件捕捉窗口的错误,即使备份映像加载失败。

img { width: 100px; height: 100px; } <script> window.addEventListener('error', windowErrorCb, { capture: true }, true) function windowErrorCb(event) { let target = event.target let isImg = target.tagName.toLowerCase() === 'img' if (isImg) { imgErrorCb() return } function imgErrorCb() { let isImgErrorHandled = target.hasAttribute('data-src-error') if (!isImgErrorHandled) { target.setAttribute('data-src-error', 'handled') target.src = 'backup.png' } else { //anything you want to do console.log(target.alt, 'both origin and backup image fail to load!'); } } } </script> <img id="img" src="error1.png" alt="error1"> <img id="img" src="error2.png" alt="error2"> <img id="img" src="https://i.stack.imgur.com/ZXCE2.jpg" alt="avatar">

重点是:

将代码放在头部,并作为第一个内联脚本执行。因此,它将侦听脚本执行后发生的错误。 使用事件捕获来捕获错误,特别是那些没有冒泡的事件。 使用事件委托,避免在每个图像上绑定事件。 在给error img元素一个backup.png文件之后,给它们一个属性,以避免backup.png文件的消失和后续的无限循环,如下所示:

img错误- - - - - - > backup.png - >错误- > backup.png - >错误- >…

更好的呼叫使用

jQuery(window).load(function(){
    $.imgReload();
});

因为使用文档。ready并不一定意味着图像被加载,只是HTML。因此,不需要延迟调用。

纯粹的JS。 我的任务是:如果图像'bl-once.png'是空的->插入第一个(没有404状态)图像从数组列表(在当前目录):

<img src=“http://localhost:63342/GetImage/bl-once.png” width=“200” onerror=“replaceEmptyImage.insertImg(this)”>

也许它需要改进,但是:

var srcToInsertArr = ['empty1.png', 'empty2.png', 'needed.png', 'notActual.png']; // try to insert one by one img from this array var path; var imgNotFounded = true; // to mark when success var replaceEmptyImage = { insertImg: function (elem) { if (srcToInsertArr.length == 0) { // if there are no more src to try return return "no-image.png"; } if(!/undefined/.test(elem.src)) { // remember path path = elem.src.split("/").slice(0, -1).join("/"); // "http://localhost:63342/GetImage" } var url = path + "/" + srcToInsertArr[0]; srcToInsertArr.splice(0, 1); // tried 1 src if(imgNotFounded){ // while not success replaceEmptyImage.getImg(url, path, elem); // CALL GET IMAGE } }, getImg: function (src, path, elem) { // GET IMAGE if (src && path && elem) { // src = "http://localhost:63342/GetImage/needed.png" var pathArr = src.split("/"); // ["http:", "", "localhost:63342", "GetImage", "needed.png"] var name = pathArr[pathArr.length - 1]; // "needed.png" xhr = new XMLHttpRequest(); xhr.open('GET', src, true); xhr.send(); xhr.onreadystatechange = function () { if (xhr.status == 200) { elem.src = src; // insert correct src imgNotFounded = false; // mark success } else { console.log(name + " doesn't exist!"); elem.onerror(); } } } } };

因此,它将插入正确的'needed.png'到我的src或'no-image.png'从当前目录。