JQuery, попълвайки опционален таг с много данни, води до срив на браузъра

Когато използвам следния код

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

има толкова много HTML, който моят javascript трябва да добави към елемента $("#dropdown"), което кара всеки браузър да се срива за няколко секунди, накрая работи както трябва и запълва падащия списък, но все пак има ли накарам браузъра ми да не се срива?


person inControl    schedule 04.10.2012    source източник
comment
Когато казвате катастрофа, всъщност имате предвид замръзване?   -  person Guffa    schedule 04.10.2012
comment
да, замръзва и Windows понякога излиза с изскачащ прозорец, тъй като тази програма не отговаря и т.н. прави същото на всеки тестван компютър.   -  person inControl    schedule 04.10.2012


Отговори (4)


Не свързвайте огромен низ, който трябва да бъде анализиран, създайте действителните елементи и поставете в select:

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: Разрушаването на обекти отнема много време във всеки браузър, много повече от създаването им. Премахването на 10 000 опции отнема около 1,5 секунди във Firefox на моя компютър, но удвояването на броя на опциите удвоява повече от два пъти времето и след около 33 000 опции времето започва да се покачва драстично. - 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 интерпретаторът на браузъра ще блокира за няколко секунди. Защо не добавите една опция наведнъж в цикъла си с помощта на append?

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

това е малко псевдокод, не знам дали се компилира, но това са моите два цента. Освен това динамичните промени в структурата на HTML винаги ще бъдат тежки, но можете да смекчите това, като разчитате на низове вместо на JS vars или jquery обекти.

person ChuckE    schedule 04.10.2012