библиотека jQuery/JavaScript, чтобы заменить сломанные изображения
У меня есть веб-страницу, которая включает в себя кучу образов. Иногда изображение недоступно, поэтому сломанное изображение отображается в браузере клиента.
Как я могу использовать jQuery, чтобы получить набор изображений, фильтровать его на сломанные изображения, а затем заменить src?
--Я думал, что было бы проще сделать это с помощью jQuery, но оказалось намного проще просто использовать чистое решение JavaScript, то есть то, которое предоставлено Prestaul.
30 ответов:
обработки
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()осуждается в 1.8 или выше.
в случае, если кто-то, как я, пытается прикрепить
errorсобытие в динамическом HTMLimgтег, я хотел бы отметить, что есть одна загвоздка:видимо
imgсобытий ошибки не пузырь в большинстве браузеров, вопреки тому, что стандартный говорит.так, что-то вроде следующего будет не работает:
$(document).on('error', 'img', function () { ... })надеюсь, что это будет полезно для кого-то еще. Жаль, что я не видел этого здесь в эта тема. Но, я не. Итак, я добавляю его
вот вам самостоятельное решение:
$(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'; } }); });
Я считаю, что это то, что вы после: jQuery.Предварительная загрузка
вот пример кода из демо, вы указываете загрузку и не нашли изображения, и вы все настроены:
$('#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
это дерьмовый метод, но это в значительной степени гарантировано:
<img ... onerror="this.parentNode.removeChild(this);">
в то время как OP искал замену SRC, я уверен, что многие люди, задающие этот вопрос, могут только хотеть скрыть сломанное изображение, и в этом случае Это простое решение отлично сработало для меня:
<img src="someimage.jpg" onerror="this.style.display='none';" />
вот быстрый и грязный способ, чтобы заменить все сломанные изображения, и нет необходимости менять 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
или для бэкэнда, узла.версия js:https://github.com/bitinn/node-fetchfetch(url) .then(function(res) { if (res.status == '200') { return image; } else { return placeholder; } }Edit: этот метод собирается заменить 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] ); }
лучше позвонить с помощью
jQuery(window).load(function(){ $.imgReload(); });потому что с помощью
document.readyНе обязательно означает, что изображения загружаются, только HTML. Таким образом, нет необходимости в отложенном вызове.
CoffeeScript вариант:
Я сделал это, чтобы исправить проблему с Turbolinks, которая вызывает .ошибка () метод, чтобы получить поднятый в Firefox иногда, даже если изображение действительно есть.
$("img").error -> e = $(@).get 0 $(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)
С помощью ответ престола, я добавил некоторые проверки, и я предпочитаю использовать способ 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С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не запускаются в то время, когда они вводятся, поэтому вы должны быть явными.
Я нашел этот пост, глядя на этот другой так пост. Ниже приводится копия ответа, который я дал там.
Я знаю, что это старый поток, но React стал популярным и, возможно, кто-то с помощью React придет сюда в поисках ответа на ту же проблему.
Итак, если вы используете React, вы можете сделать что-то вроде ниже, что было оригинальным ответом, предоставленным Беном Альпертом из команды React здесь
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\(['"](.+)['"]\)/, ''); $('<img>', { src: currentUrl }).on("error", function(e) { $this = $(this); $this.css({ "background-image": defaultUrl }) e.target.remove() }.bind(this)) })
вот пример использования объекта изображения HTML5, обернутого JQuery. Вызовите функцию load для основного URL-адреса изображения, и если эта загрузка вызывает ошибку, замените атрибут src изображения на резервный URL-адрес.
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-один раз.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(); } } } } };таким образом, он будет вставлять правильный 'необходимо.png 'для моего src или' нет-изображения.ПНГ с текущего каталога.
Я не уверен, что есть лучший способ, но я могу придумать хак, чтобы получить его - вы можете отправить Ajax на URL-адрес img и проанализировать ответ, чтобы увидеть, действительно ли изображение вернулось. Если он вернулся как 404 или что-то еще, то замените img. Хотя я ожидаю, что это будет довольно медленно.
Я решил свою проблему с помощью этих двух простых функций:
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.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] || ''; }); }); };вы можете передать путь заполнителя и получить доступ ко всем свойствам из объекта failed image через
$*:$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');
это расстраивало меня в течение многих лет. Мое исправление CSS устанавливает фоновое изображение на
img. Когда динамическое изображениеsrcне загружается на передний план, заполнитель виден наimgС БГ. Это работает, если ваши изображения имеют размер по умолчанию (например,height,min-height,widthи/илиmin-width).вы увидите значок сломанного изображения, но это улучшение. Протестировано до IE9 успешно. iOS Safari и Chrome даже не показывают сломанный икона.
.dynamicContainer img { background: url('/images/placeholder.png'); background-size: contain; }добавить немного анимации, чтобы дать
srcвремя для загрузки без фонового мерцания. Chrome плавно исчезает в фоновом режиме, но desktop 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; } }
если изображение не может быть загружено (например, потому что его нет в предоставленном URL), URL изображения будет изменен на default,
подробнее о .ошибка()
$('img').on('error', function (e) { $(this).attr('src', 'broken.png'); });
Я думаю, что у меня есть более элегантный способ с делегированием событий и захватом событий на
window' serrorдаже если образ резервной копии не удается загрузить.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 - > резервное копирование.png- > ошибка - > резервное копирование.ПНГ->ошибка->,,,,,
У меня та же проблема. Этот код хорошо работает в моем случае.
// Replace broken images by a default img $('img').each(function(){ if($(this).attr('src') === ''){ this.src = '/default_feature_image.png'; } });
иногда с помощью
errorсобытие невозможно, например, потому что вы пытаетесь сделать что-то на странице, которая уже загружена, например, когда вы запускаете код через консоль, букмарклет или сценарий, загруженный асинхронно. В таком случае, проверьте, чтоimg.naturalWidthиimg.naturalHeight0, кажется, делает трюк.например, вот фрагмент для перезагрузки всех сломанных изображений с консоли:
$$("img").forEach(img => { if (!img.naturalWidth && !img.naturalHeight) { img.src = img.src; } }
Я использую код ниже, который сначала пытается найти аватар текущего пользователя на основе их идентификатора пользователя, который в этом случае является "123", и если он не находит изображение Аватара, код onerror изменяет img src на изображение-заполнитель.
<img src="avatars/users/123.png" onerror="this.src='/ngTribeBase/src/assets/img/avatars/male.png'" />
Comments