2009-03-30 10 views
14

Mam dwa pola wyboru> < w formularzu. Wybranie pozycji w pierwszym polu wyboru> < określi, co powinno pojawić się w drugim wybierz <> (Korzystanie z Ajax http_request).Szybszy sposób na wypełnienie <select> z Javascriptem

W niektórych przypadkach może być dużych 500 (odgadnąć) przedmiotów w drugim wybierz i aktualizacja IE zajmuje 5-10 sekund. Firefox działa doskonale.

Zastanawiam się, czy istnieje szybszy sposób, aby to osiągnąć. Obecnie serwer tworzy ciąg przekazuje go do klienta, który jest następnie rozbijany i dodaje każdy element do selekcji, tworząc element opcjonalny, a następnie dodając go do wybrania> <.

Próbowałem stworzyć całą wybrać pozycję jako ciąg na serwerze i dodać, że do formy, ale z jakiegoś powodu nie działa w Firefoksie (nieodebrane coś?)

Dzięki

Odpowiedz

2

Ustawienie go przy użyciu opcji SelectElement.innerHTML będzie najszybszym ... ale that FAILS in IE.

ostatnio sprawdzałem, można to zrobić w IE, jeśli owinąć wszystkie opcje w fałszywej <div> tag lub ustawić całą .outerHTML z listy select w IE.

0

Bardzo pomogłoby zobaczyć Twój kod.

jeśli jesteś tworząc <option> elementu i dołączenie jej każdej iteracji, należy rozważyć utworzenie wszystkie <option> elementów na raz, a następnie dodanie ich wszystkich naraz.

Tak (w psuedocode):

// 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

jaki sposób korzystania z pomocy tablicy? nadal musisz wywołać {n} dołącza do listy wyboru (co jest przyczyną problemów z szybkością, ponieważ przeglądarka musi określić po każdym dołączeniu, czy rozmiar listy musi zostać zaktualizowany) – scunliffe

+0

@scunliffe - optymalizacja przeglądarki rzadko przychodzi aż do analizy złożoności Big-O. Domyślam się, że IE może opóźnić renderowanie nowych elementów opcji na ekranie, jeśli wszystkie są jednocześnie podłączone do DOM, co powinno przyspieszyć działanie. Po prostu coś do wypróbowania. – Triptych

1

chciałbym tworzyć całość wybrać na serwerze i wstrzyknąć go do strony. Takie podejście pomija irytujące rozbieżności w przeglądarkach i zmniejsza złożoność kodu po stronie klienta.

Wspomniał pan, że próbowałeś, ale nie udało się to w firefoxie. Sugerowałbym wytrwałość w uruchomieniu go, opublikowaniu kolejnego pytania z prośbą o pomoc w tej sprawie lub edytowaniu twojego pytania, aby pokazać nam, co zrobiłeś, co nie działało w firefoxie.

19

500 elementów nie jest dużo, nawet dla IE. Musisz zrobić coś innego, aby spowodować opóźnienie.

Właśnie próbowałem z ponad 500 opcjami w IE6, IE7, FF2 i FF3 i wszystkie były bliskie natychmiastowe. Użyłem tego kodu:

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)) 
} 

Proponuję profilowanie fragmentu kodu, który pobiera dane i wypełnia listę rozwijaną. Coś innego może zabierać czas. Na przykład sprawdź, czy kod, który "zrywa" wartość ciągu zwracaną przez serwer, jest ostry (brzmi, jakbyś wykonywał tam własne niestandardowe analizowanie).

+5

Um ... nie powinno to być 'select.options.add (new Option (d.text, d.value))'? – tzot

0

Gdy używam pierwszą wersję to działa, ale może być bardzo powolne w aktualizacji drugi wybrać

 
<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> 

Ta wersja działa w IE, ale firefox nie wydaje się zakładać drugie dane wybiera. Czy coś przeoczyłem z tym.

2

Problem z tymi wszystkimi odpowiedziami z SelectElement.innerHTML polega na tym, że nie można tego zrobić przy pomocy SELECTs. Rozwiązaniem jest użycie innerHTML na PARENTZE samego elementu SELECT. Tak więc w twoim ajax/jquery/dowolnym kodzie utwórz ciąg zawierający ALL z SELECT HTML, a następnie zdobądź uchwyt (div lub span lub cokolwiek innego) i ustaw innerHTML na skonstruowany ciąg.

Będziesz musiał wyizolować SELECT ze strony i nadać mu jawny element rodzica (span lub div), aby zapobiec wypadkom innych elementów html podczas niszczenia/rekonstrukcji elementu SELECT.

Krótka odpowiedź:

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

Nie zapomnij dołączyć do document.createDocumentFragment() pierwsze, że przed dołączeniem do SELECT.

4

Pierwszy kod jest w porządku, ale to działa lepiej dla mnie:

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

Lubię odpowiedzi Crescent świeży i Kemala Fadillah od czasu zarówno do użytku:

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

Co do obiektu danych polecam mała korekta w następujący sposób:

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

Jeśli nie masz nic przeciwko użyciu CoffeeScript, to następujący kod e wypełnia listę wyboru danymi JSON w kilku liniach.

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') 

Uwaga: Pętla wewnątrz append generuje całą HTML ciąg przed wywołaniem metody razappend. To jest ładne i wydajne.

Przykład JSON

[ 
    {"Id":"1","Name":"Client-1"}, 
    {"Id":"2","Name":"Client-2"} 
]