2012-03-02 8 views
1

対スクリプトもパフォーマンスの同期Iは、入力テキストの変更に基づいてフィルタDOM要素のjavascript機能を持っているので:フィルタリングするための多くのDOM要素がある場合ジャバスクリプト(jqueryの)非同期

$(".input").keyup(function(e) { 
    filter(); 
}); 

var cache = $(".dom"); 

var filter = function() { 
    cache.each(function() { 
     // if field contains some text show else hide 
    } 
}; 

私の問題が起こります、上記の例のように同期処理のため、ページ全体がアクセス不能になります。私は、同期処理でページ全体をロックしない解決策を出そうとしています。

問題はフィルタロジックに関係しません(それはまったく問題ありません).jqueryまたはjavascript自体には関係しません。同期処理およびdom要素の数量に関連しています。

答えて

0

domノードの大きなセットをキューに入れて更新し、各setTimeout "tick"に少数の要素しか処理できません。擬似コードで:

on(event): 
    queue = DOM nodes to be updated 
    setTimeout(update) 

update: 
    queue.slice(0, limit).each(...update a node...) 
    queue = queue.slice(limit) // remove processed nodes 
    if (queue.length > 0) setTimeout(update) // repeat... 

は完全に働い例えばhttp://jsfiddle.net/Etsmm/2/を参照してください。

アップデート:最初のバージョンでは、Chromeの問題(ディスプレイのバグに関連)があり、this answerのような修正が追加されたようです。

+0

jsFiddleの例では、番号が「3」のときにブラウザがフリーズします。 –

+0

重複した質問のあなたのコメントは、 "ここでは狂っている人もいます...フィルタ()関数の詳細は無関係です" *しかし、どのようにして最初のバージョンと2番目のバージョンの間のパフォーマンスを向上させましたか?それは 'フィルター'に入ったのですか?はい。私が狂ったことをもう一度教えてください。 –

+0

thg、その解決策は私が書いたものと同じですが、よりスマートな方法で行いますので、私はそれを使用します。ありがとうございました。 –

1

JavaScriptはシングルスレッドであるため、これを並べ替える唯一の方法は、長時間実行しているジョブを一連の短いジョブに分割し、各セクションの最後に短い時間遅れでsetTimeout()を使用することです次のものをキックオフする。これにより、UIや他のJavaScriptイベントを更新する機会が与えられます。

0

本当に長すぎる場合は、別の場所でAjaxリクエストを行ってください。 そして、多分、ある種の:最初のステップでは、配列内に隠すすべてのIDを選択してから、settimeoutを作成し、次に2番目のステップで、50ごとに50のように隠します。 また、すべての要素が隠されたコンテナを持っていることを処理してから、一度やり直した方が速くなるかもしれませんか?

0

以下

https://github.com/cowboy/jquery-message-queuing/

は、あなたの助けのすべてに感謝します。私はBen Claytonの回答に基づいたソリューションを考え出しましたが、まだアイを探してthg435ソリューションを調査しています。すべてのコメントは評価されます。

<script type="text/javascript"> 

     $(document).ready(function() { 

      var cache = $(".whatever"); 
      var wait = 0; 
      var input = $("#input"); 
      var regex = null; 

      input.keyup(function (e) { 
       go.index = 0; 
       clearTimeout(wait); 
       wait = setTimeout(go.start, 500); 
      }); 

      var filter = function (i) { 
       var one = cache.eq(i - 1); 
       one.text().match(regex) ? one.show() : one.hide(); 
       go.index++; 
       setTimeout(go.filter, 10); 
      }; 

      go = { 
       index: 0, 
       filter: function() { 
        go.index == 0 || go.index > cache.length ? null : filter(go.index); 
       }, 
       start: function() { 

        go.index = 1; 

        var search = input.val(); 
        search = search.replace(new RegExp("[a]", "gi"), "[aàáâã]"); 
        search = search.replace(new RegExp("[e]", "gi"), "[eéê]"); 
        search = search.replace(new RegExp("[i]", "gi"), "[ií]"); 
        search = search.replace(new RegExp("[o]", "gi"), "[oóô]"); 
        search = search.replace(new RegExp("[u]", "gi"), "[uú]"); 
        search = search.replace(new RegExp("[c]", "gi"), "[cç]"); 
        regex = new RegExp(search, "gi"); 

        go.filter(); 

       } 
      } 

     }); 

    </script> 

    <input type="text" id="input" /> 

    <span class="whatever">lalala</span> 
    <span class="whatever">leléLÉ</span> 
    <span class="whatever">lololo</span> 
    <span class="whatever">lululu</span>