2009-03-30 1 views
14

У меня есть два < выберите> коробки на форме. Выбор элемента в первом поле < select> определит, что должно появиться во втором < выберите> (используя Ajax http_request).Ускоренный способ заполнения <select> с Javascript

В некоторых случаях во втором выборе могут быть большие 500 (предположения), и для IE в IE требуется время 5-10 секунд. Firefox работает отлично.

Интересно, есть ли более быстрый способ достичь этого. В настоящее время сервер создает строку, передающую ее клиенту, который затем разбивается и добавляет каждый элемент к выбору, создавая элемент option, а затем добавляя его к < select>.

Я пытаюсь создать весь выберите пункт в виде строки на сервере и добавить, что в форме, но по какой-то причине он не будет работать в Firefox (пропустил что-то?)

Благодаря

ответ

2

Установка его с помощью SelectElement.innerHTML будет самым быстрым ... но that FAILS in IE.

Последнее, что я проверил, вы можете сделать это в IE, если вы заключаете все варианты в фиктивном <DIV> тег, или установить весь .outerHTML в списке выбора в IE.

0

Это поможет вам значительно улучшить ваш код.

Если вы создаете <option> элемент и добавив его каждую итерацию, вы должны рассмотреть вопрос о создании всех <option> элементов сразу, а затем добавив их все сразу.

Так (в 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

как же с помощью справки массива? вам все равно нужно называть {n} добавить в список выбора (что вызывает проблему скорости, так как браузер должен определить после каждого добавления, если размер списка необходимо обновить) – scunliffe

+0

@scunliffe - оптимизация браузера редко приходит вплоть до анализа сложности Big-O. Мое предположение заключалось в том, что IE может задерживать визуализацию новых элементов Option на экране, если они все были привязаны к DOM сразу, что должно ускорить процесс. Просто что-то попробовать. – Triptych

1

Я хотел бы создать весь выбрать на сервере и впрыснуть его в страницу. Этот подход обходит неудобства браузеров и снижает сложность клиентского кода.

Вы упомянули, что вы пробовали это, но это не удалось в firefox. Я бы посоветовал настойчиво добиваться его работы, опубликования другого вопроса с просьбой о помощи по этой проблеме или редактирования вашего вопроса, чтобы показать нам, что вы сделали, что не работало в firefox.

19

500 элементов не много, даже для IE. Вы должны делать что-то еще, чтобы вызвать отставание.

Я только что попробовал с более чем 500 опциями в IE6, IE7, FF2 и FF3, и все были близки мгновенно. Я использовал этот код:

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

Ум ... не должно быть 'select.options.add (new Option (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, но светлячок, кажется, не размещать данные второго выбирает. Я что-то пропустил с этим.

 
<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,. Решение состоит в том, чтобы использовать innerHTML в PARENT самого элемента SELECT. Итак, в вашем ajax/jquery/любом коде создайте строку, содержащую ВСЕ ВЫБОР HTML, а затем получите держатель (div или span или что-то еще) и установите innerHTML в строку, которую вы создали.

Вам нужно будет изолировать SELECT со страницы и предоставить ей явный родительский элемент (span или div), чтобы другие элементы html не пострадали при уничтожении/восстановлении элемента SELECT.

Короткий ответ:

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

Не забудьте приложить к document.createDocumentFragment() первых, перед добавлением, что в SELECT.

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

Мне нравится ответы Crescent Fresh в и Кемаля 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 генерирует весь HTML строку перед вызовом append метод раз. Это приятно и эффективно.

Пример JSON

[ 
    {"Id":"1","Name":"Client-1"}, 
    {"Id":"2","Name":"Client-2"} 
] 
Смежные вопросы