イメージがブラウザでレンダリングを完了した(つまりペイントされた)ときを検出するにはどうすればよいですか?

Webアプリケーションでは、DOMツリーに動的に追加される多数の高解像度画像を扱う必要があります。それらはあらかじめロードされてからページに追加されます。

このような画像の読み込みが完了したことを検出するのは、 load イベントを使用するためですが、ブラウザ内でレンダリングが完了した Javascriptを使って? 高解像度の画像を扱う場合、実際のペイントプロセスには多くの時間がかかりますが、終了する時期を知ることは非常に重要です。

22
nl ru de
@ジャック非常にそう、私は恐れている。非常に大きな解像度の画像では、少なくとも。
追加された 著者 Andrei Oniga,
ああ、私に言わないで!私はこれが私の言うことではないかと心配しました。クロスブラウザソリューションはありませんか?
追加された 著者 Andrei Oniga,
イメージの実際のレンダリングは、開発者として(エンドユーザーのコンピュータ上の)コントロールから外れている要素に非常によく似ている可能性があります。私。 CPU負荷。だから最後にはまだ「ペイント」のようなイベントが必要です。
追加された 著者 Andrei Oniga,
絵画が終わったとき、正確に何を知っておく必要がありますか?あなたのアプリケーションについてもっと教えてください。
追加された 著者 Bergi,
私はcuriuosです:これは特定のデバイスでですか?そして決議はどれくらい高いですか?
追加された 著者 Shomz,
実際にイメージの .load イベントと実際のレンダリングの間に顕著な違いがありますか?
追加された 著者 Ja͢ck,
私はFirefoxにはペイントイベントがあります。これはあなたが使用できるものかもしれません。
追加された 著者 Ja͢ck,
それはまさに正しいことです。私はオブジェクトの後ろにあります:サイズ変更されたイベント(オブジェクトの端がマウスでドラッグされると何度も起動されます)。ただし、すべてのブラウザでそれがない場合は、レンダリングイベントを追跡するのがベストです。私はそれが他の誰かによって使われているのを見ました。これは、オブジェクトの読み込みとは関係ありません。私はobject:changedイベントを使うことはできません。それは最後にのみ起こります(一度だけ)。
追加された 著者 Yoichi,
私はChromeとFFの最新の安定版を試しましたが、画像の完成した塗装とload()イベントがトリガーされるまでの間に遅延がないようです: jsfiddle.net/cbhJn/7/embedded/result
追加された 著者 adrian7,

4 答え

私はそのトリックを行うためにrequestAnimationFrameを使用しました。画像がロードされた後、次のアニメーションフレーム中にレンダリングされます。したがって、2つのアニメーションフレームを待つと、イメージがレンダリングされます。

function rendered() {
    //Render complete
    alert("image rendered");
}

function startRender() {
    //Rendering start
    requestAnimationFrame(rendered);
}

function loaded()  {
    requestAnimationFrame(startRender);
}

See http://jsfiddle.net/4fg3K/1/

10
追加された
主要なブラウザ(Edge 15、Chrome 58、FireFox 53でテスト済み)では動作しません。画像がペイントされる前に警告ボックスが表示されます。
追加された 著者 Gyum Fox,
これは、コードを画像の onload コールバックに入れると、実際に私のために働いていました。最新のChromeとFF、IE 11、Safari on iOS 10.3.3でテストされ、どこでも動作しました(画面上に画像が表示された後に警告が表示されました)。私がテストしていた画像もかなり大きかった(約2 MBのデスクトップと500 KBのモバイル)。
追加された 著者 margaretkru,

タグに onload イベントが必要です。例えば:

function loadImage() {
  alert("Image is loaded");
}

ソース

イメージが別の要素の背景である場合は、イメージをバックグラウンドでロードし(単純なAjax GETリクエストを使用して)、結果が戻ったら、ロードされた後でバックグラウンドを設定します。

1
追加された
これは私が後にしていることではありません。 Jackが指摘しているように、(絵画)!=読み込み
追加された 著者 Andrei Oniga,

更新:この方法を使用しないでください。画像のサイズがデフォルト以外の値に設定されている場合は機能しません

要素の高さをauto(固定幅)に設定し、タイムアウトを指定すると要素の寸法が画像の自然な大きさに一致するかどうかを確認し続けることができます。これは最善の解決策ではありませんが、読み込んだ後でなく、読み込んだ後に何かを行う必要が本当に必要な場合は、良い選択です。

多かれ少なかれそれがどのように見えるかです:

//this is NOT a real code
function checkIfRendered(img, onRender) {
    var elRatio = img.width()/img.height();
    var natRatio = img.naturalWidth/img.naturalHeight;

    if (elRatio === natRatio)
        onRender();
    else {
        setTimeout(function() {
            checkIfRendered(imgEl, onRender)
        }, 20);
    }
}

img.onload(checkIfRendered(img, function() { alert('rendered!'); }));
1
追加された
私はブラウザが、ペイントされているイメージのサイズではなく、ページ内の予約されたイメージスペースの高さと幅を返すと信じています。
追加された 著者 Andrei Oniga,
あなたは正しいです。画像に幅や高さを設定するCSSがある場合、この方法は正しく機能しません。だからこのapprachを使用しないでください。この返信を削除しようとしていましたが、似たような試みをする人を救うかもしれないので、ここでそれを維持します
追加された 著者 phidias,

mdn から、

MozAfterPaintイベントは、コンテンツが   再描画されたものに関する情報を提供します。それは   主にパフォーマンスの最適化を調べるために使用されます

レンダリングされた画像のパフォーマンスを測定するためにこれをやっていることを願っています。

0
追加された
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript