Bir sürü resim içeren bir web sayfam var. Bazen görüntü kullanılamayabilir, bu nedenle müşterinin tarayıcısında bozuk bir görüntü görüntülenir.
Görüntü kümesini elde etmek, kırık görüntülere filtre uygulamak ve sonra src'yi değiştirmek için jQuery'i nasıl kullanırım?
- Bunu jQuery ile yapmanın daha kolay olacağını düşündüm, ancak sadece Prestaul tarafından sağlanan saf bir JavaScript çözümü kullanmak daha kolay oldu.
JavaScript ile kaynağını yeniden atamak için görüntünün onError
olayını işleyin:
function imgError(image) {
image.onerror = "";
image.src = "/images/noimage.gif";
return true;
}
<img src="image.png" onerror="imgError(this);"/>
Veya bir JavaScript işlevi olmadan:
<img src="image.png" onError="this.onerror=null;this.src='/images/noimage.gif';" />
Aşağıdaki uyumluluk tablosu, hata özelliğini destekleyen tarayıcıları listeler:
Dahili error
işleyicisini kullanıyorum:
$("img").error(function () {
$(this).unbind("error").attr("src", "broken.gif");
});
Düzenleme: error()
yöntemi 1.8 ve daha yüksek sürümlerde kullanımdan kaldırılmıştır. Bunun yerine, .on("error")
işlevini kullanmalısınız:
$("img").one("error", function () {
$(this).attr("src", "broken.gif");
});
Benim gibi biri, error
olayını dinamik bir HTML img
etiketine eklemeye çalışırsa, şunu belirtmek isterim ki bir yakalama var:
Görünüşe göre img
hata olayları kabarcık yapma çoğu tarayıcıda, standart ne söylediğinin aksine .
Dolayısıyla, aşağıdaki gibi bir şey çalışmaz :
$(document).on('error', 'img', function () { ... })
Umarım bu başkasına yardımcı olacaktır. Keşke bunu bu başlıkta görseydim. Fakat yapmadım. Yani ekliyorum
İşte bağımsız bir çözüm:
$(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';
}
});
});
Neyin peşinde olduğuna inanıyorum: jQuery.Preload
Demodan örnek kod aşağıdadır, yükleme ve resimleri bulamıyorsunuz ve hepsini ayarladınız:
$('#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');
}
}); })
Kaynak: http://www.developria.com/2009/03/jquery-quickie---broken-images.html
İşte tüm bozuk görüntüleri değiştirmek için hızlı ve kirli bir yoldur ve HTML kodunu değiştirmenize gerek yoktur;)
$("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"),
});
}
});
OP, SRC'nin yerini almaya çalışırken, bu soruyu vuran birçok insanın yalnızca bozuk görüntüyü gizlemek isteyebileceğinden eminim, bu durumda bu basit çözüm benim için harika çalıştı:
<img src="someimage.jpg" onerror="this.style.display='none';" />
İhtiyaçlarıma uygun bir senaryo bulamadım, bu yüzden kırık görüntüleri kontrol etmek ve düzeltilinceye kadar her dört saniyede bir yeniden yüklemeye çalışmak için özyinelemeli bir işlev yaptım.
10 denemeyle sınırlandırılmışım, sanki resim sunucuda bulunmuyor ve işlev sonsuz bir döngüye giriyormuş gibi. Hala test ediyorum. Tweak çekinmeyin :)
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);
});
Bu berbat bir teknik, ama neredeyse garantili:
<img ... onerror="this.parentNode.removeChild(this);">
Bu JavaScript, çapraz tarayıcı uyumlu olmalı ve çirkin biçimlendirme olmadan teslim eder 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] );
}
Bunun için GitHub’ın kendi alımını kullanabilirsiniz:
Ön uç: https://github.com/github/fetch
veya Backend için bir Node.js sürümü: https://github.com/bitinn/node-fetch
fetch(url)
.then(function(res) {
if (res.status == '200') {
return image;
} else {
return placeholder;
}
}
Düzenleme: Bu yöntem, XHR'nin yerini alacak ve sözde Chrome'da zaten var. Gelecekte bunu okuyan kimseye, yukarıda belirtilen kütüphaneye ihtiyaç duymayabilirsiniz.
img
'nizi innerHTML
ile eklediyseniz, şöyle: $("div").innerHTML = <img src="wrong-uri">
, eğer başarısız olursa başka bir görüntüyü yükleyebilirsiniz, örneğin:
<script>
function imgError(img) {
img.error="";
img.src="valid-uri";
}
</script>
<img src="wrong-uri" onerror="javascript:imgError(this)">
Neden javascript: _
need gerekiyor? DOM'a innerHTML
komut dosyası etiketleri aracılığıyla enjekte edilen komut dosyaları enjekte edildikleri sırada çalıştırılmadığından, açık olması gerekir.
JQuery tarafından sarılmış HTML5 Image nesnesini kullanan bir örnek. Birincil görüntü URL'si için load işlevini çağırın ve bu yük bir hataya neden olursa, görüntünün src niteliğini bir yedek URL ile değiştirin.
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>
"Onerror" olayını kullanarak kırık görüntünün yerini almak için bir keman oluşturdum. Bu size yardımcı olabilir.
//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))
})
Prestaul's answer komutunu kullanarak bazı kontroller ekledim ve jQuery yöntemini kullanmayı tercih ediyorum.
<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;
}
Kullanarak daha iyi çağrı
jQuery(window).load(function(){
$.imgReload();
});
document.ready
kullanmak, görüntülerin yüklendiğini, yalnızca HTML'yi gerektirmez. Dolayısıyla, gecikmeli bir aramaya gerek yoktur.
CoffeeScript değişken:
Turbolinks ile .error () yönteminin Firefox'ta bazen görüntü gerçekten var olsa bile ortaya çıkmasına neden olan bir sorunu gidermek için yaptım.
$("img").error ->
e = $(@).get 0
$(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)
Saf JS. Görevim şuydu: 'bl-once.png' görüntüsü boşsa -> dizi listesinden (şu anki dizine) ilk (404 durumu olmayan) resmi ekleyin:
<img src="http://localhost:63342/GetImage/bl-once.png" width="200" onerror="replaceEmptyImage.insertImg(this)">
Belki de iyileştirilmesi gerekiyor, ama:
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();
}
}
}
}
};
Bu yüzden src'ye doğru 'needed.png' ya da geçerli dir'den 'no-image.png' yazacağım.
Bu yazıyı bu diğer SO yayına bakarken buldum. Aşağıda orada verdiğim cevabın bir kopyası var.
Bunun eski bir konu olduğunu biliyorum ama React popüler hale geldi ve belki de React'i kullanan biri buraya gelecek ve aynı soruyu cevaplayacak.
Yani, React'i kullanıyorsanız, aşağıdaki gibi bir şey yapabilirsiniz; bu, React of React ekibinden Ben Alpert tarafından sağlanan bir cevap aslıydı burada
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} />;
);
}
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" );
Sorunumu bu iki basit işlevle çözdüm:
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');
}
});
}
Daha iyi bir yol olup olmadığından emin değilim, ancak bunu elde etmek için bir hack düşünebilirim - Ajax'ı img URL'sine gönderebilir ve resmin gerçekten geri gelip gelmediğini görmek için yanıtı çözümleyebilirsiniz. Bir 404 ya da başka bir şey olarak geri döndü, sonra img çıkarın. Yine de bunun oldukça yavaş olmasını bekliyorum.
Bu yıllardır beni sinir ediyor. CSS düzeltmem img
'nin arkaplan görüntüsünü ayarlar. Dinamik bir görüntü src
ön plana yüklenmediğinde, img
'in bg dosyasında bir yer tutucu görünür. Bu, resimlerinizin varsayılan bir boyutu varsa çalışır (ör. height
, min-height
, width
ve/veya min-width
).
Kırık görüntü simgesini göreceksiniz ancak bu bir gelişme. IE9'a başarıyla test edildi. iOS Safari ve Chrome, bozuk bir simge bile göstermiyor.
.dynamicContainer img {
background: url('/images/placeholder.png');
background-size: contain;
}
Arka plan titremesi olmadan yüklenecek src
zamanını vermek için küçük bir animasyon ekleyin. Chrome arka planda yumuşak bir şekilde kayboluyor ancak masaüstü Safari'de yok.
.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; }
}
Yedek resim yüklenemediğinde bile olay heyeti ve window
'ın error
üzerinde olay yakalama konusunda daha şık bir yolum olduğunu düşünüyorum.
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">
Önemli olan :
Kodu head
içine yerleştirin ve ilk satır içi komut dosyası olarak çalıştırıldı. Böylece, senaryodan sonra meydana gelen hataları dinleyecektir.
Hataları yakalamak için, özellikle kabarcıklı olmayan olaylar için olay yakalamayı kullanın.
Her görüntüdeki bağlayıcı olayları engelleyen olay temsilcisi kullanın.
backup.png
öğesinin ve aşağıdaki gibi sonsuz döngünün kaybolmasını önlemek için backup.png
işlevini verdikten sonra img
öğesine bir öznitelik verin.
img error-> backup.png-> error-> backup.png-> error -> ,
Resim yüklenemiyorsa (örneğin, verilen URL’de bulunmadığından), resim URL’si varsayılan
Daha fazlası için . Error ()
$('img').on('error', function (e) {
$(this).attr('src', 'broken.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] || ''; });
});
};
Bir yer tutucu yolunu geçirebilir ve arızalı görüntü nesnesindeki tüm özelliklere $*
yoluyla erişebilirsiniz:
$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');
Bende de aynı problem var. Bu kod benim davamda iyi çalışıyor.
// Replace broken images by a default img
$('img').each(function(){
if($(this).attr('src') === ''){
this.src = '/default_feature_image.png';
}
});
Bazen error
olayını kullanmak uygun değildir, ör. çünkü önceden yüklenmiş bir sayfada, örneğin konsol üzerinden kod çalıştırırken, bir kitapçıkta veya eşzamansız olarak yüklenmiş bir komut dosyasında bir şeyler yapmaya çalışıyorsanız. Bu durumda, img.naturalWidth
ve img.naturalHeight
öğelerinin 0 olup olmadığını kontrol etmek hile yapıyor gibi görünmektedir.
Örneğin, tüm kırık görüntüleri konsoldan yeniden yüklemek için bir kod parçası:
$$("img").forEach(img => {
if (!img.naturalWidth && !img.naturalHeight) {
img.src = img.src;
}
}
Bunun en iyi sonuç verdiğini gördüm, herhangi bir görüntü ilk kez yüklenmezse, DOM'dan tamamen kaldırılır. console.clear()
işlevinin yürütülmesi, konsol penceresini temiz tutar, çünkü 404 hataları try/catch blokları ile atlanamaz.
$('img').one('error', function(err) {
// console.log(JSON.stringify(err, null, 4))
$(this).remove()
console.clear()
})