Answers:
处理onError
事件以使图像使用JavaScript重新分配其源:
function imgError(image) {
image.onerror = "";
image.src = "/images/noimage.gif";
return true;
}
<img src="image.png" onerror="imgError(this);"/>
或没有JavaScript函数:
<img src="image.png" onError="this.onerror=null;this.src='/images/noimage.gif';" />
以下兼容性表列出了支持错误工具的浏览器:
我使用内置error
处理程序:
$("img").error(function () {
$(this).unbind("error").attr("src", "broken.gif");
});
编辑:该error()
方法在jquery 1.8及更高版本中已弃用。相反,您应该使用.on("error")
改用:
$("img").on("error", function () {
$(this).attr("src", "broken.gif");
});
这是一个独立的解决方案:
$(window).load(function() {
$('img').each(function() {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
// image was broken, replace with your new image
this.src = 'http://www.tranism.com/weblog/images/broken_ipod.gif';
}
});
});
$.browser
现在已被弃用并删除,请改用功能检测(在这种情况下会变得更加复杂)。
204 No Content
,它将是损坏的图像。
我相信这就是您所追求的:jQuery.Preload
这是演示中的示例代码,您指定了加载和未找到的图像,并且一切就绪:
$('#images img').preload({
placeholder:'placeholder.jpg',
notFound:'notfound.jpg'
});
$(window).bind('load', function() {
$('img').each(function() {
if((typeof this.naturalWidth != "undefined" &&
this.naturalWidth == 0 )
|| this.readyState == 'uninitialized' ) {
$(this).attr('src', 'missing.jpg');
}
}); })
资料来源:http : //www.developria.com/2009/03/jquery-quickie---broken-images.html
在OP寻求替换SRC的同时,我敢肯定很多遇到此问题的人可能只希望隐藏破碎的图像,在这种情况下,这种简单的解决方案对我很有用。
<img src="img.jpg" onerror="this.style.display='none';" />
var images = document.querySelectorAll('img');
for (var i = 0; i < images.length; i++) {
images[i].onerror = function() {
this.style.display='none';
}
}
<img src='img.jpg' />
document.querySelectorAll('img').forEach((img) => {
img.onerror = function() {
this.style.display = 'none';
}
});
<img src='img.jpg' />
请参阅浏览器对NoteList.forEach和arrow函数的支持。
这是一种替换所有损坏图像的快捷方法,不需要更改HTML代码;)
$("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"),
});
}
});
我找不到适合自己需要的脚本,因此我创建了一个递归函数来检查损坏的图像,并尝试每四秒重新加载它们,直到它们被修复为止。
我将其限制为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);
});
您可以为此使用GitHub自己的获取:
前端: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中。对于以后阅读此书的任何人,您可能不需要包含上述库。
这是JavaScript,应该与跨浏览器兼容,并且交付时不会带有难看的标记onerror=""
:
var sPathToDefaultImg = 'http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png',
validateImage = function( domImg ) {
oImg = new Image();
oImg.onerror = function() {
domImg.src = sPathToDefaultImg;
};
oImg.src = domImg.src;
},
aImg = document.getElementsByTagName( 'IMG' ),
i = aImg.length;
while ( i-- ) {
validateImage( aImg[i] );
}
while (i--)
CoffeeScript变体:
我解决了Turbolinks的一个问题,该问题有时会导致Firefox中出现.error()方法,即使该图像确实存在。
$("img").error ->
e = $(@).get 0
$(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)
通过使用Prestaul的答案,我添加了一些检查,并且我更喜欢使用jQuery方式。
<img src="image1.png" onerror="imgError(this,1);"/>
<img src="image2.png" onerror="imgError(this,2);"/>
function imgError(image, type) {
if (typeof jQuery !== 'undefined') {
var imgWidth=$(image).attr("width");
var imgHeight=$(image).attr("height");
// Type 1 puts a placeholder image
// Type 2 hides img tag
if (type == 1) {
if (typeof imgWidth !== 'undefined' && typeof imgHeight !== 'undefined') {
$(image).attr("src", "http://lorempixel.com/" + imgWidth + "/" + imgHeight + "/");
} else {
$(image).attr("src", "http://lorempixel.com/200/200/");
}
} else if (type == 2) {
$(image).hide();
}
}
return true;
}
如果您插入了img
with innerHTML
,例如:$("div").innerHTML = <img src="wrong-uri">
,则如果加载失败,则可以加载另一个图像,例如:
<script>
function imgError(img) {
img.error="";
img.src="valid-uri";
}
</script>
<img src="wrong-uri" onerror="javascript:imgError(this)">
为什么javascript: _
需要?由于通过脚本标记插入到DOM中的脚本在innerHTML
注入时未运行,因此必须明确。
我在查看其他SO帖子时发现了此帖子。以下是我在那给出的答案的副本。
我知道这是一个旧线程,但是React已经流行起来,也许,使用React的人会来这里寻找相同问题的答案。
因此,如果您使用的是React,则可以执行以下操作,这是React团队的Ben Alpert在此处提供的原始答案。
getInitialState: function(event) {
return {image: "http://example.com/primary_image.jpg"};
},
handleError: function(event) {
this.setState({image: "http://example.com/failover_image.jpg"});
},
render: function() {
return (
<img onError={this.handleError} src={src} />;
);
}
我创建了一个小提琴,以使用“ onerror”事件替换损坏的图像。这可能对您有帮助。
//the placeholder image url
var defaultUrl = "url('https://sadasd/image02.png')";
$('div').each(function(index, item) {
var currentUrl = $(item).css("background-image").replace(/^url\(['"](.+)['"]\)/, '$1');
$('<img>', {
src: currentUrl
}).on("error", function(e) {
$this = $(this);
$this.css({
"background-image": defaultUrl
})
e.target.remove()
}.bind(this))
})
这是一个使用JQuery包装的HTML5 Image对象的示例。为主图像URL调用load函数,如果该加载导致错误,则用备用URL替换图像的src属性。
function loadImageUseBackupUrlOnError(imgId, primaryUrl, backupUrl) {
var $img = $('#' + imgId);
$(new Image()).load().error(function() {
$img.attr('src', backupUrl);
}).attr('src', primaryUrl)
}
<img id="myImage" src="primary-image-url"/>
<script>
loadImageUseBackupUrlOnError('myImage','primary-image-url','backup-image-url');
</script>
纯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();
}
}
}
}
};
因此,它将从当前目录向我的src或“ no-image.png”插入正确的“ needed.png”。
我通过以下两个简单功能解决了我的问题:
function imgExists(imgPath) {
var http = jQuery.ajax({
type:"HEAD",
url: imgPath,
async: false
});
return http.status != 404;
}
function handleImageError() {
var imgPath;
$('img').each(function() {
imgPath = $(this).attr('src');
if (!imgExists(imgPath)) {
$(this).attr('src', 'images/noimage.jpg');
}
});
}
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" );
我觉得我有事件委托和事件捕捉一个更优雅的方式window
的error
,即使备份映像加载失败。
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">
重点是 :
将代码放入中,head
并作为第一个内联脚本执行。因此,它将侦听脚本之后发生的错误。
使用事件捕获来捕获错误,尤其是对于那些不会冒泡的事件。
使用事件委托可以避免在每个图像上绑定事件。
为错误img
元素赋予一个属性后,为它们提供一个属性,backup.png
以避免消失,backup.png
随后出现无限循环,如下所示:
img错误-> backup.png->错误-> backup.png->错误-> 、、、、
let isImgErrorHandled = target.src === 'backup.png';
因为它简化了一点。
target.src='backup.png'
但下次console.log(target.src)
可能不是backup.png
;(window.jQuery || window.Zepto).fn.fallback = function (fallback) {
return this.one('error', function () {
var self = this;
this.src = (fallback || 'http://lorempixel.com/$width/$height')
.replace(/\$(\w+)/g, function (m, t) { return self[t] || ''; });
});
};
您可以通过以下方式传递占位符路径,并从失败的图像对象访问所有属性$*
:
$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');
多年来一直让我感到沮丧。我的CSS修复程序在上设置了背景图片img
。当动态图片src
未加载到前景时,占位符在img
的bg 上可见。这个工作,如果你的形象有一个默认的大小(例如height
,min-height
,width
和/或min-width
)。
您会看到损坏的图像图标,但这是一个改进。已成功测试到IE9。iOS Safari和Chrome甚至没有显示损坏的图标。
.dynamicContainer img {
background: url('/images/placeholder.png');
background-size: contain;
}
添加一些动画,以便有src
时间加载而不会闪烁背景。Chrome在背景中平滑变暗,但桌面Safari不会变暗。
.dynamicContainer img {
background: url('/images/placeholder.png');
background-size: contain;
-webkit-animation: fadein 1s;
animation: fadein 1s;
}
@-webkit-keyframes fadein {
0% { opacity: 0.0; }
50% { opacity: 0.5; }
100% { opacity: 1.0; }
}
@keyframes fadein {
0% { opacity: 0.0; }
50% { opacity: 0.5; }
100% { opacity: 1.0; }
}