2009-03-30 9 views
14

フォーム上に2つのボックスを選択します。最初の< select>ボックスの項目を選択すると、2番目の< select>(Ajax http_requestの使用)に表示される内容が決まります。JavaScriptを使用して<select>を高速に取り込む方法

場合によっては、2番目の選択に大きな500(推測)項目があり、IEで更新するには5〜10秒かかることがあります。 Firefoxは完璧に動作するようです。

これを達成するためのより迅速な方法があるのだろうかと思います。現在、サーバーは文字列を作成してそれをクライアントに渡し、クライアントは次に分割され、各項目を選択項目に追加します。これは、オプション要素を作成し、それを< select>に追加することによって行います。

私は(何かを逃した?)サーバー上の文字列として全体の選択項目を作成し、フォームにそれを追加しますが、何らかの理由でそれがFirefoxで動作しないでしょうしようとしなかった

おかげ

答えて

2

SelectElement.innerHTMLを使用して設定すると、最も速くなりますが、that FAILS in IEです。

最終私はあなたが偽の<のdiv >タグ内のすべてのオプションを包む、またはIE内の選択リストの全体.outerHTMLを設定する場合は、IEでこれを行うことができ、確認しました。

0

コードが大きく表示されます。

あなたはそれを各反復を追加<option>要素を作成している場合は、一度にすべての<option>要素を作成して、一度にすべてを追加する検討すべきです。だから、(擬似コードで)

// Don't do this: 
for choice in choices: 
    option = new Options(choice) 
    select.append(option) 


// Do this instead 
var options = array() 

for choice in choices: 
    options.append(new Options(choice)) 

for option in options: 
    select.append(option) 

// Or you might try building the select element off-screen and then appending to the DOM 
var options = array() 
var select = new SelectElement() 

for choice in choices: 
    select.append(new Options(choice)) 

dom_element.append(select) 
+0

どのように配列のヘルプを使用していますか? {n}を呼び出す必要があります(スピードの問題を引き起こすものです)。 – scunliffe

+0

@scunliffe - ブラウザーの最適化はめったに来ませんBig-Oの複雑さの分析に至りました。ここで私の推測では、IEが新しいOption要素を画面上にレンダリングするのを延期するかもしれないということでした。試してみるだけです。 – Triptych

1

私は、サーバー上のを選択し、ページに注入全体を作成します。このアプローチは、迷惑なブラウザの不一致を回避し、クライアント側のコードの複雑さを軽減します。

あなたはそれを試したことに言及しましたが、それはFirefoxで失敗しました。私はそれを働かせることに忍耐強く、その問題の助けを求める別の質問を掲示したり、Firefoxでうまくいかなかったことを私たちに示すために質問を編集したりすることをお勧めします。

19

500要素はIEの場合でさえ多くありません。あなたは遅れを引き起こすために他の何かをしなければならない。

IE6、IE7、FF2、FF3で500以上のオプションを試したところ、すべてが瞬時に近いものでした。私はこのコードを使用しました:

var data = [ 
    { text: 'foo', value: 'bar' }, 
    // ... 
    { text: 'foo', value: 'bar' } 
]; 

var select = document.getElementsByTagName('select')[0]; 
select.options.length = 0; // clear out existing items 
for(var i=0; i < data.length; i++) { 
    var d = data[i]; 
    select.options.add(new Option(d.text, i)) 
} 

私は、データを取得しているドロップダウンしているコードのビットをプロファイリングすることをお勧めします。何か他の時間がかかるかもしれない。たとえば、サーバーから返された文字列値を「分割」するコードがシャープであることを確認します(独自のカスタム解析を行っているように思えます)。

+5

Um ... 'select.options.add(新しいオプション(d.text、d.value))'ではないでしょうか? – tzot

0

私はこれの最初のバージョンを使用する場合、それは動作しますが、更新が非常に遅くなることが二

 
<html> 
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'> 
<table> 
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> 
<tr><td><select id='selectid'></select></td></tr> 
</table> 
</form> 
</html> 

<script type=\"text/javascript\"> 
function UPDATE(updatedata) 
{     
    var itemid = document.getElementById('selectid');    

    var data = updatedata.split('|'); 
    var len = data.length;               

    for(i=0; i < len; i ++) 
    { 
     var opt = document.createElement('option'); 
     opt.text = data[i]; 

     try 
     { 
      itemid.add(opt, null);       
     } 
     catch(ex) 
     { 
      itemid.add(opt);  
     }  
    }           
} 
</script> 

を選択し、このバージョンでは、IEで動作しますが、Firefoxのは、第二の選択データを掲載していないようです。私はこれで何かを逃したことがありますか?

 
<html> 
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'> 
<table> 
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> 
<tr><td><div id='addselect'></div></td></tr> 
</table> 
</form> 
</html> 

<script type=\"text/javascript\"> 
function UPDATE(updatedata) 
{    
    // update data is full select html 
    var itemid = document.getElementById('addselect');    
    itemid.innerHTML = updatedata;               
} 
</script> 
2

SelectElement.innerHTMLを使用したこれらの回答の問題は、SELECTを使用してこのトリックを実行できないことです。解決方法は、SELECT要素自体のPARENTでinnerHTMLを使用することです。したがって、あなたのajax/jquery/whateverコードでは、SELECT HTMLのすべてを含む文字列を作成し、次にホルダー(divやspanなど)を取得し、作成した文字列にinnerHTMLを設定します。

SELECT要素を破棄/再構築するときに、他のhtml要素が犠牲にならないように、ページからSELECTを分離し、明示的な親要素(spanまたはdiv)を与える必要があります。

短い答え:

parentselectelement.removeChild(selectelement); 
parentselectelement.innerHTML = "<select ...><options...></select>"; 
1

はSELECTにそれを追加する前に、document.createDocumentFragment()最初に追加することを忘れないでください。

4

最初のコードは結構ですが、これは私のためにうまく機能:

var data = [ 
    { text: 'uno', value: '1' }, 
    {text: 'dos', value: '2' } 
]; 

var select = document.getElementById('select-choice-1'); 
select.options.length = 0; // clear out existing items 
for (var i = 0; i < data.length; i++) { 
    var d = data[i]; 
    select.options.add(new Option(d.text, d.value)) 
} 
0

私はクレセント新鮮なのと使用の両方以来、ケマル・Fadillahの答えのように:

select.options.add(new Options(name, value)) 

を私はお勧めのデータオブジェクトについて小さな調整を以下に示します。

var data = { 
    'uno': 1, 
    'dos': 2 
}; 

var select = document.getElementById('select-choice-1'); 
select.options.length = 0; // clear out existing items 
for (var i in data) { 
     select.options.add(new Option(i, data[i])); 
} 
0

CoffeeScriptを使用しても構わない場合は、以下のコードeは、選択リストに数行のJSONデータを埋め込みます。

HTML

<select id="clients"></select> 

CoffeeScriptの

fillList=($list, url)=> 
    $.getJSON(url) 
    .success((data)-> 
     $list 
     .empty() 
     .append("<option value=\"#{item.Id}\">#{item.Name}</option>" for item in data) 
    ) 

$ -> 
    fillList($('#clients'), '/clients/all') 

append内部ループはappend方法一度呼び出す前に、全体のHTML文字列を生成します。これは素晴らしく効率的です。

例JSON

[ 
    {"Id":"1","Name":"Client-1"}, 
    {"Id":"2","Name":"Client-2"} 
] 
関連する問題