我有一个网页,里面有很多图片。有时映像不可用,因此在客户机的浏览器中显示一个损坏的映像。
我如何使用jQuery来获取图像集,过滤它到破碎的图像,然后替换src?
—我本以为用jQuery会更容易做到这一点,但事实证明使用纯JavaScript解决方案更容易,也就是Prestaul提供的解决方案。
我有一个网页,里面有很多图片。有时映像不可用,因此在客户机的浏览器中显示一个损坏的映像。
我如何使用jQuery来获取图像集,过滤它到破碎的图像,然后替换src?
—我本以为用jQuery会更容易做到这一点,但事实证明使用纯JavaScript解决方案更容易,也就是Prestaul提供的解决方案。
当前回答
jQuery 1.8
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.error(function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
jQuery 3
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.on("error", function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
参考
其他回答
纯粹的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'从当前目录。
我认为我有一个更优雅的方式与事件委托和事件捕捉窗口的错误,即使备份映像加载失败。
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 - >错误- >…
你可以使用GitHub自己的fetch:
前端:https://github.com/github/fetch 或者在后端,一个Node.js版本:https://github.com/bitinn/node-fetch
fetch(url)
.then(function(res) {
if (res.status == '200') {
return image;
} else {
return placeholder;
}
}
编辑:这个方法将取代XHR,据说已经在Chrome。对于将来阅读这篇文章的人来说,您可能不需要包含上述库。
jQuery 1.8
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.error(function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
jQuery 3
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.on("error", function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
参考
我找不到适合我需要的脚本,所以我做了一个递归函数来检查损坏的图像,并尝试每四秒重新加载它们,直到它们修复。
我将它限制为10次尝试,因为如果它没有加载,那么图像可能不会出现在服务器上,函数将进入一个无限循环。不过我仍在测试中。请随意调整它:)
var retries = 0;
$.imgReload = function() {
var loaded = 1;
$("img").each(function() {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
var src = $(this).attr("src");
var date = new Date();
$(this).attr("src", src + "?v=" + date.getTime()); //slightly change url to prevent loading from cache
loaded =0;
}
});
retries +=1;
if (retries < 10) { // If after 10 retries error images are not fixed maybe because they
// are not present on server, the recursion will break the loop
if (loaded == 0) {
setTimeout('$.imgReload()',4000); // I think 4 seconds is enough to load a small image (<50k) from a slow server
}
// All images have been loaded
else {
// alert("images loaded");
}
}
// If error images cannot be loaded after 10 retries
else {
// alert("recursion exceeded");
}
}
jQuery(document).ready(function() {
setTimeout('$.imgReload()',5000);
});