【问题标题】:JQuery filling an option tag with a lot of data makes browser crashJQuery用大量数据填充选项标签会导致浏览器崩溃
【发布时间】:2012-10-04 18:33:28
【问题描述】:

当我使用以下代码时

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

我的 javascript 必须添加太多 HTML 到 $("#dropdown") 元素中,这会使任何浏览器崩溃几秒钟,最后它可以正常工作并填满下拉列表,但是无论如何让我的浏览器不会崩溃?

【问题讨论】:

  • 当你说“crash”时,你的意思是真的“freeze”吗?
  • 是的,冻结,有时窗口会弹出一个窗口,因为这个程序没有响应等。它在每台测试的计算机上做同样的事情。

标签: jquery html crash generated-code


【解决方案1】:

不要连接必须解析的大字符串,创建实际元素并放入选择中:

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 个选项元素。

无论如何,如果您有这么多选择,您可能应该重新考虑 UI...

【讨论】:

  • 你给我的代码有效,但我还是有同样的问题。
  • 抱歉,我的问题已经解决了,但是当我清空一个非常大的选项列表时,它不会在填充选项时滞后/冻结/崩溃。
  • 您是否尝试过清空该选项字段?因为它对我来说冻结/崩溃了。
  • 抱歉问题似乎只出在 mozilla firefox
  • @inControl:在任何浏览器中拆除对象都需要很长时间,比创建它们要长得多。在我的电脑上的 Firefox 中删除 10000 个选项大约需要 1.5 秒,但选项数量增加一倍多时间,大约 33000 个选项后时间开始急剧上升。
【解决方案2】:

StringBuffer usage in javascript in place of string concatenations

String concatenation vs string buffers in 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;
};

【讨论】:

    【解决方案3】:

    不确定这是否会为您加快速度,但为什么不直接附加到下拉列表?

    $.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);
    

    【讨论】:

      【解决方案4】:

      首先是 $.map 的使用。与来自 JS 的 for 相比,它的性能有所不同。另一件事是 .html 的使用。推荐,但是如果你有很多数据,浏览器JS解释器会阻塞几秒钟。为什么不使用 append 在循环中一次添加一个选项?

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

      它有点伪代码,不知道它是否编译,但这是我的两分钱。除此之外,HTML 结构的动态更改总是很繁重,但是您可以通过依赖字符串而不是 JS vars 或 jquery 对象来缓解这种情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-20
        • 1970-01-01
        • 1970-01-01
        • 2014-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多