JQuery, заполняющий тег параметра большим количеством данных, приводит к сбою браузера

Когда я использую следующий код

var html = "";
$.map(data.modelTypes, function (item) {
    html+= "<option>" + item.type + "</option>";
});
$("#drowdown").html(html);

мой javascript должен добавить так много HTML к элементу $("#dropdown"), что это приводит к сбою любого браузера на пару секунд, в конце концов он работает как надо и заполняет выпадающий список, но есть ли в любом случае чтобы мой браузер не вылетал?


person inControl    schedule 04.10.2012    source источник
comment
Когда вы говорите об аварии, вы на самом деле имеете в виду заморозку?   -  person Guffa    schedule 04.10.2012
comment
да, зависание, и Windows иногда появляется всплывающее окно, поскольку эта программа не отвечает и т. Д. Она делает то же самое на каждом тестируемом компьютере.   -  person inControl    schedule 04.10.2012


Ответы (4)


Не объединяйте огромную строку, которую необходимо проанализировать, создайте фактические элементы и поместите их в выборку:

var options = $.map(data.modelTypes, function (item) {
  return $('<option>', { text: item.type })[0];
});
$("#drowdown").empty().append(options);

Примечание. Вы использовали метод map как each, вы должны вернуть значение в функцию, после чего вы получите массив значений, возвращаемых методом map.

Редактировать:

Некоторые тесты показывают, что использование более простого Javascript вместо использования jQuery для зацикливания и создания элементов делает его в два раза быстрее:

var options = [];
for (var i =0; i < data.modelTypes.length; i++) {
  var o = document.createElement('OPTION');
  o.text = data.modelTypes[i].type;
  options.push(o);
}
$("#drowdown").empty().append(options);

На моем компьютере в Firefox это добавляет 1000000 опций примерно за секунду.

В любом случае, если у вас так много вариантов, вам, вероятно, следует переосмыслить пользовательский интерфейс...

person Guffa    schedule 04.10.2012
comment
Код, который вы мне дали, работает, но у меня все та же проблема. - person inControl; 04.10.2012
comment
Извините, моя проблема в некотором роде исправлена, но всякий раз, когда я очищаю очень большой список параметров, он отстает / зависает / вылетает не при заполнении одного. - person inControl; 04.10.2012
comment
Вы пробовали очистить это поле? потому что он зависает/вылетает для меня на этом. - person inControl; 04.10.2012
comment
Извините, проблема только в mozilla firefox. - person inControl; 04.10.2012
comment
@inControl: удаление объектов занимает много времени в любом браузере, намного больше времени, чем их создание. Удаление 10000 опций занимает около 1,5 секунд в Firefox на моем компьютере, но удвоение количества опций увеличивает время более чем в два раза, а после примерно 33000 опций время начинает резко увеличиваться. - person Guffa; 04.10.2012

Использование StringBuffer в javascript в место объединения строк

Конкатенация строк и буферы строк в Javascript

Конкатенация строк — очень медленная операция. Вы должны использовать строковый буфер.

function StringBuffer() {
this.__strings__ = new Array;
}

StringBuffer.prototype.append = function (str) {
    this.__strings__.push(str);
};

StringBuffer.prototype.toString = function () {
    return this.__strings__.join("");
};


StringBuffer.prototype.empty = function(){
    this.__strings__.length = 0;
};
person Zahid Riaz    schedule 04.10.2012

Не уверен, что это ускорит работу для вас, но почему бы не добавить напрямую в раскрывающийся список?

$.each(data.modelTypes, function(i, value) {
        $('#drowdown').append($('<option>').text(value).attr('value', value));

Поскольку в вашем случае у вас есть огромный список элементов, вы можете рассмотреть возможность использования DocumentFragment. Что-то в духе:

var dropdown= $("#drowdown").empty();

var frag = document.createDocumentFragment();
data.modelTypes.each( function(item) {
    frag.appendChild($('<option>').text(item).attr('value', item));
});

dropdown.append(frag);
person tranceporter    schedule 04.10.2012

Во-первых, это использование $.map. У него плохая производительность по сравнению с for из JS. Другое дело — использование .html. Рекомендуется, но если у вас много данных, JS-интерпретатор браузера заблокируется на несколько секунд. Почему бы вам не добавлять по одной опции в свой цикл с помощью добавления?

for (i = 0; i < data.modelTypes.length; i++) {
  $("#drowdown").append("<option>"+data.modelTypes[i].type+"</option>")); 
}

это немного псевдокод, не знаю, компилируется ли, но это мои пять копеек. Помимо этого, динамические изменения структуры HTML всегда будут тяжелыми, но вы можете смягчить это, полагаясь на строки вместо переменных JS или объектов jquery.

person ChuckE    schedule 04.10.2012