2011-08-05 5 views
4

私はJavascriptを使用してUIを構築するライブラリを持っています。動的コンテンツが含まれているため、コンテンツをブラウザに入れてレイアウトを変更してサポートし、結果に応じて別のロジックを実行する必要があります。たとえば、あるテキストがあふれているかどうかを検出し、省略記号で切り捨てます。javascriptを使用して、保留中のレイアウト変更をブラウザに強制的にフラッシュすることはできますか?

通常、私は変更を加え、レイアウトを更新して残りのロジックを呼び出すのを待つためにwindow.setTimeout(0)を使用して実装します。これは、異なるブラウザが最小限のタイムアウトを実装しているため、ちらつきを防止するには遅すぎるか、または多くのCPUを使用する速度が遅いため、明らかに最適ではありません。

理想的には、DOMの変更を行い、レイアウトを同期して更新し、直ちにインラインで「フィックスアップ」ロジックを実行したいと考えています。何か案は?

+0

わかりません。遅い最小タイムアウトを伴うsetTimeout(0)がフリッカを引き起こすのはなぜですか? – Alohci

+0

最小タイムアウトが長すぎる場合(100msを超えるとすると)、私が行う更新チェーンはちらつきを引き起こします:最初のステップは何かを行い、次に2番目のステップはそれを修正し、3番目のステップは何か他のことを行います - すべてを一度に行うのではなく、 – Guss

答えて

2

我々はIE8(Firefoxの、クロムは問題あり)とクレイジー問題が発生しました。子要素に対してtoggleClass( 'enoMyAddressesHide')を使用します。

.enoMyAddressesHide{display:none} 

ただし、親divコンテナは、その高さをリフレッシュ/再レイアウトしません。

setTimeout()、要素の読み取り位置、読み取り幅、および高さは役に立ちません。 最後に、我々は実用的なソリューションを見つけることができます。

jQuery(document).ready(function ($) { 
    var RefreshIE8Layout = function() { 
     $('.enoAddressBook:first').css('height', 'auto'); 
     var height = $('.enoAddressBook:first').height(); 
     $('.enoAddressBook:first').css('height', height); 
    }; 

    $(".enoRowAddressInfo .enoRowAddressInfoArea ul li img.enoMyAddresses").click(function() { 
     $(this).parent().find(".enoAllInfoInAddressBox,img.enoMyAddresses").toggleClass('enoMyAddressesHide'); 

     RefreshIE8Layout(); // fix IE8 bug, not refresh the DOM dimension after using jQuery to manipulate DOM 
    }); 
}); 

それは愚かに見えるが、それは動作します!

+0

これは面白そうです。特定の値に設定した後に高さを 'auto'にリセットすると、リフロー動作が保持されると思いますか?私は本当に高さをまだ自動にしたいと思っています。 – Guss

+0

私のテストでは@Guss(Win7のIE8ネイティブブラウザで)、私たちがしなければならないのは**高さのCSS'プロパティの変更**です。あなたは何か( '100%、50px'、...)に変更してから、' auto'に戻すことができます。 –

+0

私はいつそれを試みるのかは分かりませんが(最近他のプロジェクトに忙しいですが)、私が探していたもののように見えるので、私はあなたの答えを受け入れるつもりです。ありがとう! – Guss

6

私の理解では、CSSプロパティのいずれかを読むと、リフローが強制されます。 setTimeoutはまったく必要ありません。

Rendering: repaint, reflow/relayout, restyleからの抜粋:

しかし、時にはリフローを最適化からブラウザを防止し、そしてそれがキューをフラッシュし、すべてのバッチ処理の変更を実行する可能性があり、スクリプト。あなたは、本質的にノードに関するスタイル情報を要求している以上、このような

offsetTop, offsetLeft, offsetWidth, offsetHeight 
scrollTop/Left/Width/Height 
clientTop/Left/Width/Height 
getComputedStyle(), or currentStyle in IE 

として、これらのすべてのスタイル情報を要求する場合に発生し、そしてあなたがそれを行う任意の時点では、ブラウザはあなたに、最新のを与えることがあります値。そうするためには、すべてのスケジュールされた変更を適用し、キューをフラッシュし、弾を噛んでリフローを実行する必要があります。

Here's a list of the API calls/properties that will trigger a reflow

+0

これらはリフローを引き起こす可能性がありますが、実際のリフローは直ちに(〜同期的に)行われるとは思われません。編集:私はあなたのリンク 'あなたのスクリプトに必要な変更のキューを設定し、それらをバッチで実行するのを見ているのを見た。 – BiAiB

+1

私がしていることはあなたが記述したようにレイアウトのプロパティを読み込もうとするが、ブラウザ(特にIE)では、プロパティがまだ変更されていないため、変更が反映されていないため、うまく機能しません。 – Guss

+0

true、 'clientHeight'、' currentStyle'はIE8で即座に反映されませんでした – Nikhil

0

私は、これは実際にあなたの実装のために働くだろうという考えを持っていませんが、:

var myDiv = document.getElementById("myDiv"); 
myDiv.innerHTML = "".concat(myDiv.innerHTML); 

私はinnerHTMLプロパティを設定すると、子要素のDOMのリロードを強制することを信じています。私はあなたがこれを全サイトにスコープしたらどうなるか分かりません。あなたはDOMのどこにでもよく夢中になっているように思えます。この方法では、あなたが既に定義したノード参照を強制的に未定義にするかもしれません。言い換えれば、

var mySelect = document.getElementById("mySelect");// suppose this lives in myDiv. 
var myDiv = document.getElementById("myDiv"); 
myDiv.innerHTML = "".concat(myDiv.innerHTML); 

上記の例では、mySelectへの参照が失われると思います。このようなことがたくさんあり、ゲッターではないフィールドを使用している場合(つまり、アクセスするたびに$()または$ getまたはdocument.getElementById(..)このタイプのフラッシングがあなたを襲う可能性が非常に高いです。

また、手動でトラッキング/設定していないページ状態データを失うこともありえます。ユーザーからの新しいテキストを含むテキストボックス、ユーザーが新たにチェックしたチェックボックスなどは、この方法を使用してデフォルト状態に再初期化されますフラッシュする。

幸運なコーディング!

B

+0

さて、これはバストです:私はコントロールしていない多くの事を壊すので、私はページ全体を再レンダリングしようとしていません。 – Guss

0

はい、できます。

ほとんどのブラウザでは、変更をキューに入れてバッチで実行することで、リフロープロセスが最適化されます。レンダリングツリーの変更をフラッシュするには、レイアウト情報(オフセット計算、getComputedStyle()、およびスクロール値)を取得する必要があります。

var el = document.getElementById("my-element"); 
var top = el.offsetTop; 

上記のコードは、ブラウザが正しい値を返すためにレンダリングキューの変更を実行するよう強制します。

シンプルに!

+0

それはまったく行いません。 –

関連する問題