たくさんの画像を含む Web ページがあります。画像が利用できない場合があるため、壊れた画像がクライアントのブラウザーに表示されます。
jQueryを使用して一連の画像を取得し、それを壊れた画像にフィルタリングしてからsrcを置き換えるにはどうすればよいですか?
-- jQuery を使った方が簡単だと思っていたのですが、Prestaul が提供する純粋な JavaScript ソリューションを使用する方がはるかに簡単であることがわかりました。
たくさんの画像を含む Web ページがあります。画像が利用できない場合があるため、壊れた画像がクライアントのブラウザーに表示されます。
jQueryを使用して一連の画像を取得し、それを壊れた画像にフィルタリングしてからsrcを置き換えるにはどうすればよいですか?
-- jQuery を使った方が簡単だと思っていたのですが、Prestaul が提供する純粋な JavaScript ソリューションを使用する方がはるかに簡単であることがわかりました。
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");
});
編集:このメソッドは、 jquery 1.8error()
以降では非推奨です。代わりに、次を使用する必要があります。.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';
}
});
});
これがあなたが求めているものだと思います:jQuery.Preload
デモのサンプル コードは次のとおりです。読み込み中の画像と見つからない画像を指定すると、すべての設定が完了します。
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
これは壊れた画像をすべて置き換える手っ取り早い方法で、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"),
});
}
});
ニーズに合ったスクリプトが見つからなかったので、再帰関数を作成して壊れた画像をチェックし、修正されるまで 4 秒ごとに再読み込みを試みました。
それまでにロードされていないかのように、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 に含まれています。将来これを読む人にとっては、前述のライブラリを含める必要はないかもしれません。
を使用してより良い呼び出し
jQuery(window).load(function(){
$.imgReload();
});
使用document.ready
することは、画像が読み込まれることを意味する必要はないため、HTMLのみが読み込まれます。したがって、通話を遅らせる必要はありません。
Prestaul's answerを使用して、いくつかのチェックを追加し、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;
}
(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');
より良い方法があるかどうかはわかりませんが、それを取得するためのハックを考えることができます.Ajaxでimg URLに投稿し、応答を解析して、画像が実際に戻ってきたかどうかを確認できます. 404 か何かとして戻ってきた場合は、img を交換します。これはかなり遅いと思いますが。
これら2つの単純な関数で問題を解決しました:
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');
}
});
}
error
コンソール、ブックマークレット、または非同期でロードされたスクリプトを介してコードを実行している場合など、既にロードされているページで何かを実行しようとしている場合など、イベントを使用できない場合があります。その場合、img.naturalWidth
とimg.naturalHeight
が 0 であることを確認するとうまくいくようです。
たとえば、壊れたすべてのイメージをコンソールからリロードするためのスニペットを次に示します。
$$("img").forEach(img => {
if (!img.naturalWidth && !img.naturalHeight) {
img.src = img.src;
}
}
jQuery1.8
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.error(function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
jQuery3
// If missing.png is missing, it is replaced by replacement.png
$( "img" )
.on("error", function() {
$( this ).attr( "src", "replacement.png" );
})
.attr( "src", "missing.png" );
私は遅延ロードを使用しており、適切に機能させるためにこれを行う必要があります:
lazyload();
var errorURL = "https://example.com/thisimageexist.png";
$(document).ready(function () {
$('[data-src]').on("error", function () {
$(this).attr('src', errorURL);
});
});