Saya memiliki halaman web yang mencakup banyak gambar. Terkadang gambar tidak tersedia, jadi gambar yang rusak ditampilkan di browser klien.
Bagaimana cara menggunakan jQuery untuk mendapatkan set gambar, memfilternya ke gambar yang rusak kemudian mengganti src?
--Saya pikir akan lebih mudah untuk melakukan ini dengan jQuery, tetapi ternyata lebih mudah untuk hanya menggunakan solusi JavaScript murni, yaitu, yang disediakan oleh Prestaul.
Tangani acara onError
agar gambar dipindahkan ulang sumbernya menggunakan JavaScript:
function imgError(image) {
image.onerror = "";
image.src = "/images/noimage.gif";
return true;
}
<img src="image.png" onerror="imgError(this);"/>
Atau tanpa fungsi JavaScript:
<img src="image.png" onError="this.onerror=null;this.src='/images/noimage.gif';" />
Tabel kompatibilitas berikut mencantumkan browser yang mendukung fasilitas kesalahan:
Saya menggunakan handler error
bawaan:
$("img").error(function () {
$(this).unbind("error").attr("src", "broken.gif");
});
Edit: Metode error()
tidak digunakan lagi dalam 1.8 dan lebih tinggi. Sebagai gantinya, Anda harus menggunakan .on("error")
sebagai gantinya:
$("img").one("error", function () {
$(this).attr("src", "broken.gif");
});
Jika seseorang seperti saya, mencoba untuk melampirkan acara error
ke tag HTML img
dinamis, saya ingin menunjukkan bahwa, ada masalah:
Tampaknya peristiwa kesalahan img
jangan gelembung di sebagian besar browser, bertentangan dengan apa yang standar katakan .
Jadi, sesuatu seperti yang berikut ini akan tidak berfungsi :
$(document).on('error', 'img', function () { ... })
Semoga ini bisa membantu orang lain. Saya berharap saya telah melihat ini di sini di utas ini. Tapi saya tidak melakukannya. Jadi, saya menambahkannya
Ini adalah solusi mandiri:
$(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';
}
});
});
Saya yakin inilah yang Anda cari: jQuery.Preload
Berikut ini contoh kode dari demo, Anda menentukan pemuatan dan tidak menemukan gambar dan Anda siap:
$('#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');
}
}); })
Sumber: http://www.developria.com/2009/03/jquery-quickie---broken-images.html
Berikut adalah cara cepat dan kotor untuk mengganti semua gambar yang rusak, dan tidak perlu mengubah kode 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"),
});
}
});
Sementara OP ingin mengganti SRC, saya yakin banyak orang yang memukul pertanyaan ini mungkin hanya ingin menyembunyikan gambar yang rusak, dalam hal ini solusi sederhana ini bekerja sangat baik untuk saya:
<img src="someimage.jpg" onerror="this.style.display='none';" />
Saya tidak dapat menemukan skrip yang sesuai dengan kebutuhan saya, jadi saya membuat fungsi rekursif untuk memeriksa gambar yang rusak dan berusaha memuatnya kembali setiap empat detik hingga diperbaiki.
Saya membatasinya hingga 10 upaya seolah-olah itu tidak dimuat maka gambar mungkin tidak ada di server dan fungsinya akan memasuki infinite loop. Saya masih mengujinya. Jangan ragu untuk meng-tweak-nya :)
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);
});
Ini adalah teknik yang jelek, tapi cukup dijamin:
<img ... onerror="this.parentNode.removeChild(this);">
Ini JavaScript, harus kompatibel lintas browser, dan dikirim tanpa markup jelek 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] );
}
Anda dapat menggunakan pengambilan GitHub sendiri untuk ini:
Frontend: https://github.com/github/fetch
atau untuk Backend, versi Node.js: https://github.com/bitinn/node-fetch
fetch(url)
.then(function(res) {
if (res.status == '200') {
return image;
} else {
return placeholder;
}
}
Sunting: Metode ini akan menggantikan XHR dan konon sudah ada di Chrome. Bagi siapa pun yang membaca ini di masa mendatang, Anda mungkin tidak perlu menyertakan perpustakaan yang disebutkan di atas.
Jika Anda telah memasukkan img
Anda dengan innerHTML
, seperti: $("div").innerHTML = <img src="wrong-uri">
, Anda dapat memuat gambar lain jika gagal melakukannya, misalnya, ini:
<script>
function imgError(img) {
img.error="";
img.src="valid-uri";
}
</script>
<img src="wrong-uri" onerror="javascript:imgError(this)">
Mengapa javascript: _
needed? Karena skrip yang disuntikkan ke DOM melalui tag skrip di innerHTML
tidak dijalankan pada saat disuntikkan, jadi Anda harus eksplisit.
Berikut adalah contoh menggunakan objek Gambar HTML5 yang dibungkus oleh JQuery. Panggil fungsi memuat untuk URL gambar utama dan jika memuat itu menyebabkan kesalahan, ganti atribut src gambar dengan URL cadangan.
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>
Saya membuat biola untuk mengganti gambar yang rusak menggunakan acara "onerror". Ini dapat membantu Anda.
//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))
})
Dengan menggunakan jawaban Prestaul , saya menambahkan beberapa cek dan saya lebih suka menggunakan cara 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;
}
Lebih baik menggunakan panggilan
jQuery(window).load(function(){
$.imgReload();
});
Karena menggunakan document.ready
tidak perlu menyiratkan bahwa gambar dimuat, hanya HTML. Dengan demikian, tidak perlu untuk panggilan yang tertunda.
CoffeeScript varian:
Saya membuatnya untuk memperbaiki masalah dengan Turbolinks yang menyebabkan metode .error () muncul di Firefox kadang-kadang meskipun gambarnya benar-benar ada.
$("img").error ->
e = $(@).get 0
$(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)
JS murni. Tugas saya adalah: jika gambar 'bl-once.png' kosong -> masukkan yang pertama (yang tidak memiliki status 404) gambar dari daftar array (dalam direktori saat ini):
<img src="http://localhost:63342/GetImage/bl-once.png" width="200" onerror="replaceEmptyImage.insertImg(this)">
Mungkin perlu ditingkatkan, tetapi:
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();
}
}
}
}
};
Jadi, itu akan memasukkan 'diperlukan.png' yang benar ke src saya atau 'no-image.png' dari dir saat ini.
Saya menemukan posting ini sambil melihat ini _ _ lainnyaSO posting . Di bawah ini adalah salinan dari jawaban yang saya berikan di sana.
Saya tahu ini adalah utas lama, tetapi Bereaksi menjadi populer dan, mungkin, seseorang yang menggunakan Bereaksi akan datang ke sini mencari jawaban untuk masalah yang sama.
Jadi, jika Anda menggunakan React, Anda dapat melakukan sesuatu seperti di bawah ini, yang merupakan jawaban asli yang diberikan oleh Ben Alpert dari tim React di sini
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" );
Saya memecahkan masalah saya dengan dua fungsi sederhana ini:
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');
}
});
}
Saya tidak yakin apakah ada cara yang lebih baik, tapi saya bisa memikirkan hack untuk mendapatkannya - Anda bisa Ajax memposting ke URL img, dan mengurai respons untuk melihat apakah gambar benar-benar kembali. Jika kembali sebagai 404 atau sesuatu, maka tukar keluar img. Meskipun saya berharap ini sangat lambat.
Ini telah membuat saya frustasi selama bertahun-tahun. Perbaikan CSS saya menetapkan gambar latar belakang pada img
. Saat gambar dinamis src
tidak dimuat ke latar depan, placeholder terlihat di b__ img
. Ini berfungsi jika gambar Anda memiliki ukuran default (mis. height
, min-height
, width
dan/atau min-width
).
Anda akan melihat ikon gambar yang rusak tetapi ini merupakan peningkatan. Diuji ke IE9 berhasil. iOS Safari dan Chrome bahkan tidak menampilkan ikon yang rusak.
.dynamicContainer img {
background: url('/images/placeholder.png');
background-size: contain;
}
Tambahkan sedikit animasi untuk memberi src
waktu untuk memuat tanpa flicker latar belakang. Chrome memudar di latar belakang dengan lancar tetapi desktop Safari tidak.
.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; }
}
Saya pikir saya memiliki cara yang lebih elegan dengan delegasi acara dan acara menangkap di window
's error
bahkan ketika gambar cadangan gagal dimuat.
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">
Intinya adalah :
Masukkan kode ke dalam head
dan dieksekusi sebagai skrip inline pertama. Jadi, itu akan mendengarkan kesalahan yang terjadi setelah skrip.
Gunakan menangkap peristiwa untuk menangkap kesalahan, terutama untuk peristiwa yang tidak menggelembung.
Gunakan delegasi acara yang menghindari peristiwa mengikat pada setiap gambar.
Berikan elemen img
atribut atribut setelah memberi mereka backup.png
untuk menghindari hilangnya backup.png
dan loop tak terbatas berikutnya seperti di bawah ini:
img error-> backup.png-> error-> backup.png-> error -> ,
Jika gambar tidak dapat dimuat (misalnya, karena tidak ada di URL yang disediakan), URL gambar akan diubah menjadi default,
Untuk informasi lebih lanjut tentang . 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] || ''; });
});
};
Anda dapat melewati jalur placeholder dan mengakses semua properti dari objek gambar yang gagal melalui $*
:
$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');
Saya mendapat masalah yang sama. Kode ini berfungsi dengan baik pada kasus saya.
// Replace broken images by a default img
$('img').each(function(){
if($(this).attr('src') === ''){
this.src = '/default_feature_image.png';
}
});
Terkadang menggunakan acara error
tidak layak, mis. karena Anda mencoba melakukan sesuatu pada halaman yang sudah dimuat, seperti ketika Anda menjalankan kode melalui konsol, bookmarklet, atau skrip yang dimuat secara tidak sinkron. Dalam hal ini, memeriksa apakah img.naturalWidth
dan img.naturalHeight
adalah 0 sepertinya berhasil.
Misalnya, inilah cuplikan untuk memuat ulang semua gambar yang rusak dari konsol:
$$("img").forEach(img => {
if (!img.naturalWidth && !img.naturalHeight) {
img.src = img.src;
}
}
Saya menemukan ini bekerja paling baik, jika ada gambar gagal memuat pertama kali, itu sepenuhnya dihapus dari DOM. Menjalankan console.clear()
menjaga jendela konsol tetap bersih, karena kesalahan 404 tidak dapat dihilangkan dengan blok coba/tangkap.
$('img').one('error', function(err) {
// console.log(JSON.stringify(err, null, 4))
$(this).remove()
console.clear()
})