web-dev-qa-db-ja.com

jQueryを使って画像がロードされている(エラーがない)か確認する

私はJavaScriptをjQueryライブラリと組み合わせて、番号なしリストに含まれている画像のサムネイルを操作しています。イメージがロードされるとそれは1つのことを行います、エラーが発生するとそれは別のことをします。私はjQueryのload()とerror()メソッドをイベントとして使っています。 これらのイベントの後、jQueryがイベントを登録することができるようになる前に、image DOM要素で.completeをチェックしてイメージがまだロードされていないことを確認します。

jQueryがイベントを登録する前にエラーが発生した場合を除いて、正しく動作します。私が考えることができる唯一の解決策は、img onerror属性を使用してグローバルにどこかに "フラグ"を格納することです。それが失敗したと言うのでjQueryは.completeをチェックするときその "store/node"をチェックすることができます。

誰より良い解決策がありますか?

編集:要点を太字にし、以下に追加の詳細を追加しました。画像に完成度のエラーイベントを追加した後で、画像が完成したかどうかを確認しています。そのように、イベントが登録される前にイメージがロードされていたとしても、私はまだ知っています。イベントの後にイメージがロードされていない場合、イベントはそれを処理します。これに関する問題は、画像がすでにロードされているかどうかを簡単に確認できることですが、代わりにエラーが発生したかどうかはわかりません。

202
William

もう1つのオプションは、メモリ内イメージ要素を作成し、そのonload属性を元のイメージの元のonerror属性に設定することによって、srcまたはsrcのイベントを発生させることです。これが私の言っていることの一例です。

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;

お役に立てれば!

231
Xavi

completeおよびnaturalWidthプロパティをこの順序で確認します。

https://stereochro.me/ideas/detecting-broken-images-js

function IsImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren’t downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (img.naturalWidth === 0) {
        return false;
    }

    // No other way of checking: assume it’s ok.
    return true;
}
211
SLaks

img要素のW3C HTML仕様 に対する私の理解に基づいて、 completenaturalHeight の組み合わせを使用してこれを実行できるはずです。次のような属性

function imgLoaded(imgElement) {
  return imgElement.complete && imgElement.naturalHeight !== 0;
}

complete 属性の仕様から:

以下のいずれかの条件に該当する場合、IDL属性completeはtrueを返す必要があります。

  • Src属性は省略されています。
  • リソースがフェッチされた後にネットワーキングタスクソースによってキューに入れられた最後のタスクがキューに入れられました。
  • Img要素は完全に利用可能です。
  • Img要素が壊れています。

それ以外の場合、属性はfalseを返す必要があります。

そのため、completeは、イメージの読み込みが完了した場合、または読み込みに失敗した場合にtrueを返します。イメージが正常にロードされた場合だけが欲しいので、 nauturalHeight 属性もチェックする必要があります。

IDL属性のnaturalWidthおよびnaturalHeightは、画像が使用できる場合はCSSピクセル単位で、画像の固有の幅と高さを返す必要があります。それ以外の場合は0を返します。

そして available は次のように定義されています。

Imgは常に次のいずれかの状態にあります。

  • 利用不可 - ユーザーエージェントは画像データを取得していません。
  • 部分的に利用可能 - ユーザーエージェントは画像データの一部を取得しました。
  • 完全に利用可能 - ユーザーエージェントはすべての画像データを取得しており、少なくとも画像のサイズは利用可能です。
  • 壊れている - ユーザーエージェントはそれができるすべての画像データを得ました、しかしそれは画像寸法を得るのに十分な画像をデコードすることさえできません。画像が壊れているか、フォーマットがサポートされていないか、データを取得できませんでした。

Img要素が部分的に利用可能な状態または完全に利用可能な状態にあるとき、それは利用可能であると言われます。

そのため、イメージが "壊れている"(ロードに失敗した)場合は、利用可能な状態ではなく "壊れた"状態になるため、naturalHeightは0になります。

したがって、imgElement.complete && imgElement.naturalHeight !== 0をチェックすると、イメージが正常にロードされたかどうかがわかります。

これについての詳細は、 img要素のW3C HTML仕様 、または MDNの場合 にあります。

50
Ajedi32

私はさまざまな方法を試してみましたが、この方法が私には唯一の方法です

//check all images on the page
$('img').each(function(){
    var img = new Image();
    img.onload = function() {
        console.log($(this).attr('src') + ' - done!');
    }
    img.src = $(this).attr('src');
});

すべての画像がDOMにロードされ準備ができたときに呼び出されるコールバック関数を追加することもできます。これは動的に追加された画像にも当てはまります。 http://jsfiddle.net/kalmarsh80/nrAPk/

18
Kal

imagesLoaded javascript library を使用してください。

普通のJavascriptで、そしてjQueryプラグインとして使える。

特徴:

リソース

11
Josh Harrison

ページ上の画像要素から情報を取得する
ChromeとFirefoxでのテスト作業
Working jsFiddle (結果を見るにはコンソールを開いてください)

$('img').each(function(){ // selecting all image element on the page

    var img = new Image($(this)); // creating image element

    img.onload = function() { // trigger if the image was loaded
        console.log($(this).attr('src') + ' - done!');
    }

    img.onerror = function() { // trigger if the image wasn't loaded
        console.log($(this).attr('src') + ' - error!');
    }

    img.onAbort = function() { // trigger if the image load was abort
        console.log($(this).attr('src') + ' - abort!');
    }

    img.src = $(this).attr('src'); // pass src to image object

    // log image attributes
    console.log(img.src);
    console.log(img.width);
    console.log(img.height);
    console.log(img.complete);

});

注:私は jQuery を使用しましたが、これはフルJavaScriptで達成できると思いました

私はここで良い情報を見つけます OpenClassRoom - >これはフランスのフォーラムです

4
Julha

リアルタイムネットワークディテクタ - ページを更新せずにネットワークの状態を確認します。(jqueryではありませんが、テスト済み、100%動作:(Firefox v25.0でテスト済み))

コード:

<script>
 function ImgLoad(myobj){
   var randomNum = Math.round(Math.random() * 10000);
   var oImg=new Image;
   oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
   oImg.onload=function(){alert('Image succesfully loaded!')}
   oImg.onerror=function(){alert('No network connection or image is not available.')}
}
window.onload=ImgLoad();
</script>

<button id="reloadbtn" onclick="ImgLoad();">Again!</button>

接続が失われた場合は、もう一度Againボタンを押してください。

pdate 1:ページを更新せずに自動検出します。

<script>
     function ImgLoad(myobj){
       var randomNum = Math.round(Math.random() * 10000);
       var oImg=new Image;
       oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
       oImg.onload=function(){networkstatus_div.innerHTML="";}
       oImg.onerror=function(){networkstatus_div.innerHTML="Service is not available. Please check your Internet connection!";}
}

networkchecker = window.setInterval(function(){window.onload=ImgLoad()},1000);
</script>

<div id="networkstatus_div"></div>
3
Jenei Tamás

上記の方法を組み合わせてクロスブラウザで動作させるには、次のようにします(イメージを動的にdomに挿入する必要もありました)。

$('#domTarget').html('<img src="" />');

var url = '/some/image/path.png';

$('#domTarget img').load(function(){}).attr('src', url).error(function() {
    if ( isIE ) {
       var thisImg = this;
       setTimeout(function() {
          if ( ! thisImg.complete ) {
             $(thisImg).attr('src', '/web/css/img/picture-broken-url.png');
          }
       },250);
    } else {
       $(this).attr('src', '/web/css/img/picture-broken-url.png');
    }
});

注:isIE変数に有効なブール状態を指定する必要があります。

2
Justin Vincent

このページのおもしろい解決策を読んだ後、私はSLaksとNoyoの投稿に強く影響されて、Chrome、IE、Firefox、Safari、そして(執筆の時点で)最新バージョンに取り組んでいるような使いやすい解決策を作成しましたOpera(全てWindows上)また、私が使ったiPhone/iPadエミュレータでも動作しました。

このソリューションとSLaksおよびNoyoの投稿との大きな違いの1つは、このソリューションでは主にnaturalWidthプロパティとnaturalHeightプロパティがチェックされることです。現在のバージョンのブラウザでは、これら2つのプロパティが最も有用で一貫した結果を提供するように思われることを私は発見しました。

このコードは、イメージが完全にANDで正常にロードされたときにTRUEを返します。イメージがまだ完全にロードされていないか、ORがロードに失敗した場合は、FALSEを返します。

注意が必要なことの1つは、画像が0x0ピクセルの画像の場合、この関数もFALSEを返すことです。しかし、これらの画像はあまり一般的ではなく、0x0ピクセルの画像がまだロードされているかどうかを確認したいという非常に便利なケースは考えられません。

最初に、 "isLoaded"という新しい関数をHTMLImageElementプロトタイプに添付して、その関数を任意の画像要素で使用できるようにします。

HTMLImageElement.prototype.isLoaded = function() {

    // See if "naturalWidth" and "naturalHeight" properties are available.
    if (typeof this.naturalWidth == 'number' && typeof this.naturalHeight == 'number')
        return !(this.naturalWidth == 0 && this.naturalHeight == 0);

    // See if "complete" property is available.
    else if (typeof this.complete == 'boolean')
        return this.complete;

    // Fallback behavior: return TRUE.
    else
        return true;

};

それから、画像のロード状態をチェックする必要があるときはいつでも、単に "isLoaded"関数を呼び出します。

if (someImgElement.isLoaded()) {
    // YAY! The image loaded
}
else {
    // Image has not loaded yet
}

SLaksとNoyoの投稿に対するgiorgianのコメントによると、SRC属性を変更することを計画している場合、このソリューションはおそらくSafari Mobileでの1回限りのチェックとしてしか使用できません。しかし、既存の画像要素のSRC属性を変更するのではなく、新しいSRC属性を持つ画像要素を作成することでこれを回避できます。

2
data-dan

私が理解しているように、.completeプロパティは標準的ではありません。それは普遍的ではないかもしれません...私はそれがFirefox対IEで異なって動くように見えることに気づきます。私はJavascriptでいくつかの画像をロードしていて、それが完了したかどうかをチェックしています。 Firefoxでは、これはうまくいくようです。 IEでは、画像が別のスレッドにロードされているように見えるからではありません。 image.srcへの割り当てとimage.completeプロパティのチェックとの間に遅延を置いた場合にのみ機能します。

Image.onloadとimage.onerrorを使っても私にはうまくいきません。なぜなら、関数が呼ばれたときに私が話している画像を知るためにパラメータを渡す必要があるからです。実際には同じ関数の異なるインスタンスではなく、同じ関数を渡すように見えるため、これを行う方法はいずれも失敗するようです。そのため、イメージを識別するために渡した値は、常にループの最後の値になります。この問題を回避することはできません。

SafariとChromeでは、エラーコンソールにその画像の404が表示されている場合でも、image.completeがtrueに設定され、naturalWidthが設定されているのを確認しています。しかし、上記はFirefoxとIEではうまくいきます。

1
user1018645

このコードの断片は、ブラウザのキャッシュの問題を修正するのに役立ちました。

$("#my_image").on('load', function() {

    console.log("image loaded correctly"); 
}).each(function() {

     if($(this).prop('complete')) $(this).load();
});

ブラウザのキャッシュが無効になっていると、このコードだけでは動作しません。

$("#my_image").on('load', function() {
     console.log("image loaded correctly"); 
})

うまく機能させるには、追加する必要があります。

.each(function() {
     if($(this).prop('complete')) $(this).load();
});
1
Frank
var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

//またはプラグインとして

    $.fn.extend({
      isLoaded: function(){
        return this.prop("complete") && this.prop("naturalWidth") !== 0;
      }
    })

// $(".myImage").isLoaded() 
1
KhaledDev

これは私のためにうまくいった:)

$('.progress-image').each(function(){
    var img = new Image();
    img.onload = function() {
        let imgSrc = $(this).attr('src');
        $('.progress-image').each(function(){
            if($(this).attr('src') == imgSrc){
                console.log($(this).parent().closest('.real-pack').parent().find('.shimmer').fadeOut())
            }
        })
    }
    img.src = $(this).attr('src');
});
0
Kannan Uthaman

このJavaScriptコードを使用して、イメージが正常にロードされたかどうかを確認できます。

document.onready = function(e) {
        var imageobj = new Image();
        imageobj.src = document.getElementById('img-id').src;
        if(!imageobj.complete){ 
            alert(imageobj.src+"  -  Not Found");
        }
}

これを試してみる

0
Ajay Gupta

私は、画像とEventListenerの完全なロードに関して多くの問題を抱えていました。

何を試しても、結果は信頼できませんでした。

しかし、それから私はその解決策を見つけました。技術的にはいいものではありませんが、今では失敗したイメージのロードはありませんでした。

私がしたこと:

                    document.getElementById(currentImgID).addEventListener("load", loadListener1);
                    document.getElementById(currentImgID).addEventListener("load", loadListener2);

                function loadListener1()
                    {
                    // Load again
                    }

                function loadListener2()
                {
                    var btn = document.getElementById("addForm_WithImage"); btn.disabled = false;
                    alert("Image loaded");
                }

画像を1回読み込むのではなく、1回目の直後に2回読み込むだけで、両方ともイベントハンドラを介して実行されます。

私の頭痛はすべてなくなりました。


ところで:あなたはstackoverflowからあなたたちはすでに百回以上私を助けてくれました。これはとても大きいですありがとうございました!

0
Scoobeedo Cool