1

jspページを使用して、DBからデータを取得することによって動的に生成されるスライドメニュー(選択/オブジェクトhtmlメニュー)を使用しています。

また、スライド メニューから検索できる入力テキスト フィールドもあります。メニューに含まれる単語の語根を書きたいのですが、メニューを「サイズ変更」して、書き込んだ語根を持つすべてのアイテムとそれらのアイテムのみを表示する必要があります。

サーバー側の操作 (ポスト経由でデータを送信するなど) は使用できませんが、このクライアント側を解決する必要があります (この結果がすぐに必要になるため)。

実際に JavaScript を使用してこの問題を解決しましたが、IE 8 を使用する必要があるため、このソリューションにはパフォーマンス上の問題があります。

JQueryまたはAjaxを使用した同様のソリューションはありますか?

ここに私のコードに似たものがあります:

HTML:

<select multiple id="testSelect">
    <option>test</option>
    <option>temp</option>
    <option>cast</option>
    <option>dest</option>
    <option>inst</option>
</select>

<input type="text" value="" onkeyup="searhSelect(this)" />​

search 関数は、キーを押すたびに (ユーザーが実際にキーを離したときに) 呼び出され、#testSelect オブジェクトをフィルタリングします。

JS:

var optionsList;
function searhSelect(el) {
    var select = document.getElementById('testSelect');
    if(!optionsList) {        
        optionsList = select.cloneNode(true);  //copy select to a variable for future use      
    }
    select.innerHTML = "";//remove all options.

    for(var i =0; i < optionsList.options.length; i++) {
        var opt = optionsList.options[i];
        if(opt.innerHTML.indexOf(el.value) != -1) {
            select.appendChild(opt.cloneNode(true));
        } 
    }
}
4

2 に答える 2

1

次のようなコードを試してください。

var optionsList = [];
function searhSelect(el) {
    var select = document.getElementById('testSelect');

    if(optionsList.length == 0) {        
        for(var i = 0; i < select.options.length; i++)
            optionsList[i] = {key:select.options[i].value,value:select.options[i].innerHTML}; //copy select to a variable for future use      
    }   
    //if(el.value.length > 2) {
        var tmp = "<select id=\"testSelect\" mulitple=\"multiple\" size=\"4\">";
        for(var i =0; i < optionsList.length; i++) {
            var opt = optionsList[i];
            if(opt.value.indexOf(el.value) != -1) {                 
                tmp += ' <option value="' + opt.key + '" >' + opt.value + '</option> ';                        
            }         
        }   
        document.getElementById('test').innerHTML = tmp + "</select>";
    //}

}

HTML:

<div id="test">
   <select multiple id="testSelect">
      <option>test</option>
      <option>temp</option>
      <option>cast</option>
      <option>dest</option>
      <option>inst</option>
      <!-- in my test same options you see above were copy/pasted many times. I had little more than 10k  options->
   </select>
</div>

すべての clone/appendChild を削除し、すべての要素を int 配列にプッシュし、値とテキスト フィールドを含むオブジェクトを格納しました。最も重要なことは、オプションが innerHTML で作成されるようになったことです。また、select は別の div でラップされていることに注意してください。また、select の innerHTML を使用して単に options HTML を設定する代わりに、select HTML 全体を含む文字列が作成されます ( var tmp = "<select id=\"testSelect\" mulitple=\"multiple\" size=\"4\">";)。これは、IE のこのバグの回避策として必要です。

現在の実装では、各オプションが見つかると、1 つずつ追加されます。そうすれば、IE は新しいオプションが追加されるたびに要素をレンダリングします ()。ただし、上記のコードは、すべてのオプションが定義されているときに一度だけレンダリングを強制します。残念ながら、それは部分的にしか役に立ちません。質問のコードよりも高速に動作しますが、新しい選択要素をレンダリングするのに約 10 秒 (古いコードの 20 ~ 30 秒と比較して) かかります ( document.getElementById('test').innerHTML = tmp + "</select>";-この時点で、ブラウザーが 10 秒間フリーズしています)。

いくつかのグローバルな変更を加えずに高速化できるとは思いません (たとえば、要素を選択するためのチェックボックスを使用したカスタム複数選択、display:block/none で要素を表示/非表示にする)。考えられる解決策 - フィルタリングされた要素が比較的少ない場合にのみ、要素を更新します。たとえば、検索する値の長さが 2 文字を超える場合 (コメントアウトを参照//if(el.value.length > 2) {)。しかし、それを使用するには、現在の実装では追加のコーディングが必要です (少なくとも、ユーザーが入力フィールドからいくつかの文字を削除すると、完全なリストが再度表示されるはずです)。

于 2012-12-11T12:37:24.383 に答える
0

オートコンプリートのようなことをしようとしていると思います。http://api.jqueryui.com/autocompleteを試しましたか?

それとも、単にSELECTオプションを除外したいですか?次に、クローンを作成するよりも、非表示/無効にする方が簡単だと思います。

于 2012-12-11T10:46:46.257 に答える