2016-10-08 2 views
1

元々、display: noneという多数の子要素を持つ巨大なdivがありましたが、それをdisplay: ''に設定するとdiv全体が表示されます。これは顕著な遅れを生み出した。タイムアウトで要素を1つずつ表示することでスロットルしたいのですが、作成した関数が奇妙な動作を引き起こします。 setTimeoutを削除しても、実際には正常に動作しますが、setTimeoutがない場合でも、同じ遅延があります。再帰関数を使用したdivとchildrenのスロットル表示

function throttleDisplay(page) { 
    page.style.display = ''; 
    var children = page.children; 
    if (!children.length) return; 
    for (var i = 0; i < children.length; i++) { 
     var child = children[i]; 
     setTimeout(function() { 
      throttleDisplay(child); 
     }, 100); 
    } 
} 
+1

あなたは何かを置くことができますか? – Siddharth

+0

残念ながら、ウェブページの内容は私的である –

+0

デモコンテンツや何かを作る、私たちが手助けしたい – Siddharth

答えて

1

いくつかの問題があります。

  1. 全てアットワンスただ1つのページの再フローと再ペイントをトリガーするdisplay:block(またはdisplay:'')を設定することにより、トップレベル<div>を明らかにし、そのため再帰的に明らかに子供たちよりも少ない「遅れ」を作成しますこれは、指数関数的な再フローと再塗装でレイアウトをスラッシュします。

  2. setTimeout(したがって、そのコールバックは)素子兄弟ない、多かれ少なかれ同時に(一方の再帰階層で)forループ内のそれぞれの子のために呼び出され、これは子孫の要素明らかにする絞りれます。

  3. ツリー内のすべての要素がdisplay:noneで始まる場合を除き、最上位要素をdisplay:''に設定すると、ツリーは一括で表示されます。

トップレベル<div>があなたの遅れの原因であることは確かですか? コードサンプルは、コミュニティがあなたの問題の原因を見つけるのに役立つかもしれません。最初の提案は、displayを変更して​​のコードを改行することです。 (MDN on rAF

注1A:それぞれの子要素を1つのコンテナ要素に対して個別に表示するため、「指数関数」と言いますが、操作の数は相対的なコンテナを無視して子孫の総数に対して線形です"/"包含された "状態。

注1B:必ずしもこのコードがレイアウトを「スラッシュ」するわけではありません。すべての関数呼び出しがフレームのスペース(〜17ms)内で処理できるという条件で、おそらく最新のブラウザでフレームの最後に自動的にバッチ処理されるレイアウトへの一連の「書き込み」を実行しています。無制限の兄弟の暴力についてしか話していない。非同期スロットリングは、コードの他の部分からの「読み込み」を許可し、再フローを強制しますが、遅延はすでに5フレームの長さであるため、これは無関係です。要点は、このコードはどんな種類の「遅れ」も減らさないということです。

+0

はいすべての要素には表示がありません。私はパート2で本当に混乱しています。 –

+0

更新:requestAnimationFrameはちょっと役に立ったがまだ気づいていない –

+1

@DanielKobe 'for'ループの各繰り返しで、100msの遅延で' setTimeout'を呼び出します。これは非同期操作です。 'for'ループは、100msが経過するのを待たずに継続します。したがって、 'setTimeout'への呼び出しは各子に対して「同時に」起こります。 100ms後、コールバック関数( 'throttleDisplay')は各子に対して「同時に」呼び出されます。したがって、DOMツリーでは明らかに*レベル*の間に100msの遅延がありますが、同じ親要素の子(「兄弟」)の間では100msの遅延があります。 –

0

私が持っていた機能に関するいくつかの問題を説明してくれたこのvidorに感謝します。私はjsbin上で偽のデータを再現しようとしたため、同じ問題を抱えていなかったので、私の特定の状況では、まさに奇妙な動作を引き起こしていたのか分かりません。私はこのような特定の状況のた​​めのカスタム関数を構築することを決めました

Messages: function (page) { 
    var messageCount = 0; 
    var curThrottle = 0; 
    page.style.display = ''; 
    var children = page.children; 
    var lastChild = children[children.length - 1]; 
    var lastChildsChildren = lastChild.children; 
    for (var i = 0; i < lastChildsChildren.length; i++) { 
     var child = lastChildsChildren[i]; 
     child.style.display = ''; 
     var messages = child.children[child.children.length - 1].children; 
     for (var j = 0; j < messages.length; j++) { 
      if (++messageCount%40 === 0) curThrottle += 30; 
      var message = messages[j]; 
      (function (message) { 
       setTimeout(function() { 
        message.style.display = ''; 
       }, curThrottle); 
      })(message); 
     } 
    } 
}