2013-11-02 10 views
6

私は、AJAX経由で配信されるHTMLを注入しているWebページを持っています。私は知らない、先験的、コンテンツのサイズが、私はそのサイズに基づいてページ上のコンテンツを配置する必要があります。ブラウザが挿入された要素をペイントし終わったときを判断する方法は?

  1. セット親コンテナの不透明度を0
  2. にDOMにコンテンツを挿入します。ここでは動作しません単純なアプローチです。
  3. サイズを測定します。 $el.outerWidth(true)
  4. これらのサイズに基づいてコンテンツを配置します。
  5. 親コンテナの不透明度(背面)を1.0に設定します。

このアプローチの問題は、内容がかなり複雑であり、画像が含まれていることです。 outerWidth()が呼び出されると、ブラウザはまだ画面の再描画を完了しておらず、返されるサイズが正確ではありません。 (興味深いことに、私の場合、当初の次元は常に0より大きくはなく、最終的な値よりもかなり大きい)。

手順2と3の間にタイマーを設定することで問題を軽減できますが、私はタイマーを作って、それを越えるいくつかのシステムには確かにいくつかのブラウザがあるでしょう。また、ほとんどのケースをカバーするためにタイマーを長くすると、不必要な遅延が発生するため、より高速なシステムでユーザーに不利益を与えます。以下に参照される回答のうちのいくつかはsetTimeout(fn, 0)で十分であると示唆していますが、私はそれが当てはまるわけではないことを発見しました。私は2012年のMacBook Airで塗装時間を60ミリ秒まで測定しました。以下の1つの答えは500ミリ秒を示唆しています。

Mozillaは一度に私の問題を解決したかもしれないonPaint eventを持っていたようです。それがまだ存在し、他のブラウザがそれを採用していれば。 (どちらもそうではありません)そして、Mutation Observersは要素の変更を報告するときに塗装時間を考慮していないようです。

解決策またはコメントは非常に高く評価されました。以下に述べるように、これは前に尋ねられましたが、ほとんどの質問は少なくとも1歳であり、私はもう一度やり直すことが必死です。残念ながら、実行可能な答えを提供していない


関連質問


更新:まあ、単にこの問題に対する一般的な解決策がない表示されます。私の具体的なケースでは、コンテンツが読み込まれ、レイアウトが完了すると、確実に変更されるプロパティが見つかりました。 JavaScriptはこのプロパティの変更をポーリングします。それほどエレガントではありませんが、それは私が見つけることができる最良の選択肢でした。

+0

何ディスプレイ 'とDOMに追加することについて:(' setTimeout'で)実行を延期、NONE'とその高さ/幅に基づいて物事を整理しますか? –

+0

イメージがダウンロードされたら、 'load'イベントは起動されませんか?そして一度取り出された画像の大きさではありませんか?画像をビューポートの外にレンダリングしてから、ブラウザが実際に寸法を計算するのに必要な場所にCSSを含めるようにしてください。再描画が完了する前にonloadイベントが発生するため、 – Kiruse

答えて

-1

ウィンドウの読み込みがトリックを行うかどうかを確認できます。新しいコンテンツが読み込まれたときに、複数回起動されるかどうかはわかりません。

しかし、画像の場合は、このようなものを使用できます。

//ロード完了した画像を照合した後、関数を呼び出し

function imagesLoadedEvent(selector, callback) { 
    var This = this; 
    this.images = $(selector); 
    this.nrImagesToLoad = this.images.length; 
    this.nrImagesLoaded = 0; 

    //check if images have already been cached and loaded 
    $.each(this.images, function (key, img) { 
     if (img.complete) { 
      This.nrImagesLoaded++; 
     } 
     if (This.nrImagesToLoad == This.nrImagesLoaded) { 
      callback(This.images); 
     } 
    }); 

    this.images.load(function (evt) { 
     This.nrImagesLoaded++; 
     if (This.nrImagesToLoad == This.nrImagesLoaded) { 
      callback(This.images); 
     } 
    }); 
} 

$("#btn").click(function() { 
    var c = $("#container"), evt; 
    c.empty(); 
    c.append("<img src='" + $("#img1").val() + "' width=94>"); 
    c.append("<img src='" + $("#img2").val() + "' width=94>"); 
    c.append("<img src='" + $("#img3").val() + "' width=94>"); 
    evt = new imagesLoadedEvent("img", allImagesLoaded); 
}); 

function allImagesLoaded(imgs) { 
    //this is called when all images are loaded 
    //console.log("all " + imgs.length + " images loaded"); 
} 

js fiddle for images loaded

+0

onloadは機能しません。また、私の場合、コンテンツは画像ではなくマークアップ(画像を含む場合も含まない場合もあります)です。 –

+0

画像が含まれていない場合は、各マークアップブロックの最後に透明/非表示/ 1px * 1ピクセルの画像を追加して、最後に追加する画像と、ロードが完了しました。前述のように –

+0

の場合、再描画が完了する前にアンロードイベントが発生するため、アンロードは機能しません。 (また、この特定のケースでは、とにかくコンテンツを制御できません) –

関連する問題