2

バックグラウンド

HTML要素用のjQueryベースのシャトルウィジェットを開発しました。これは、最小限に体系化され、発音区別符号selectを補正する正規表現フィルターを提供するウィジェットが見つからなかったためです。

問題

に数千のエントリが追加されるselectと、正規表現フィルターの速度が低下します。次のように問題を確認できます。

  1. 参照先:http://jsfiddle.net/U8Xre/2/
  2. 結果パネルの入力フィールドをクリックします。
  3. 正規表現を入力します(例:)^a.*ai

コード

私は犯人がここに潜んでいると信じています:

var options = $src.empty().scrollTop( 0 ).data( "options" );
var search = $.trim( $input.val() );
var regex = new RegExp( search, 'gi' );
var len = options.length;
var $html = $(document.createElement( 'option' ));
for( var i = 0; i < len; i++ ) {
  var o = options[ i ];
  if( o.text.dediacritics().match( regex ) !== null ) {
    $src.append( $html.clone().text( o.text ).val( o.value ) );
  }
}
$src.css( 'width', $input.width() + 4 );

$srcソースはどこ$('#select')にありString.prototype.dediacritics、フィドルのように定義されています。上記のコードは、キーを押すたびに実行されます。もう1つの関連するスニペットがあります:

// Create a copy of the source options to use when matching the regex.
var $options = [];
$src.find( "option" ).each( function() {
  $options.push( { value: $(this).val(), text: $(this).text() } );
});
$src.data( "options", $options );

これにより、ソースリストからオプションのコピーが作成されますが、実行されるのは1回だけです。(これにより、オプションをシャトルするときに重複のバグが発生しますが、上記のコードをinputイベントハンドラーに追加すると、フィルターの速度がさらに低下します。)

質問

最大5,000語のリストに対してほぼリアルタイムで正規表現フィルタリングを実行するようにコードを作成するにはどうすればよいですか?

ありがとうございました!

4

3 に答える 3

1

私はあなたに提案します

  • すべてのオプション名のリストを含む複数行の文字列を、それぞれ別の行に作成します
  • この複数行の文字列に正規表現を適用して、一致しない行を削除してコンテンツをフィルタリングします
  • select要素のオプションとして一致する行でhtmlを更新します
于 2012-11-26T01:03:36.187 に答える
1

検索を行うよりも(多くの正規表現置換を使用して)を繰り返し呼び出すのが難しい仕事だと思いdediacritics()ます(ただし、プロファイリングは行っていません)。したがって、これらの非暗号化文字列をキャッシュして、それらのみを検索する必要があります。ところで、test通常はより高速ですmatch

また、できるだけ多くのDOM操作を避ける必要があります。キーを押してオプションリスト全体を空にして再度追加する場合は、多くのDOM操作があります。

// once:
var options = [],
    src = $src[0]; // or whatever to get the DOM element
$.each( src.options, function() {
    options.push( { el: this, text: $(this).text().dediacritics(), hidden:false } );
});
// you might put it on the element via .data(), but need not

// onkeypress:
var regex = new RegExp( $.trim($input.val()), 'i' );
var curEl = src.firstChild;
for (var i=0; i<options.length; i++) {
    var option = options[i];
    if (regex.test( option.text )) {
        if (option.hidden)
            src.insertBefore(option.el, curEl);
        curEl = option.el.nextSibling;
        option.hidden = false;
    } else {
        if (!option.hidden) {
            curEl = option.el.nextSibling;
            src.removeChild(option.el);
        }
        option.hidden = true;
    }
}

デモ:これは非常に高速(「リアルタイム」)ですが、 5000回options呼び出すと、配列を作成するのに必要な時間を感じることができます。dediacritics()

于 2012-11-26T01:34:06.797 に答える
1

マイナーコメント、正規表現の一致の結果を使用していない場合は、正規表現テストを使用する必要があります。

  if( o.text.dediacritics().match( regex ) !== null ) {

テストを使用します。

  if( regex.test(o.text.dediacritics()) ) {
于 2012-11-26T04:51:19.540 に答える