Javascript从JSON有效地构建表并将其添加到DOM

我有一个JSON数组从服务器进来,有一个包含200个对象的数组,每个对象包含另外10个我希望以表格格式显示的对象。 起初我为每次迭代创建了一个

,并使用jQuery将从数组值构建的

附加到

。 这在Chrome中大约需要30秒,在IE 8中大约需要19秒。这需要太长时间,所以我尝试切换到Array.join()方法,在那里我将存储构成整个表的每个字符串,最后做$('#myTable').append(textToAppend) 。 这实际上比我的第一个版本差了大约5秒钟。

我想把这个大约10秒钟。 我有机会吗? 如果没有,我只是一次添加一行,但我宁愿不这样做。

 for(allIndex = 0; allIndex < entries.alumnus.length; allIndex++){ var entry = ''; $('#content_table').append(entry); $('#entry' + allIndex).append(($.trim(entries.alumnus[allIndex].title) != '' ? '' + entries.alumnus[allIndex].title + '' : '' + filler + '')); . . . .//REST OF ELEMENTS . . . } 

更新:昨天我一定搞砸了,因为我回去尝试从DOM中添加元素然后在不使用jQuery的情况下附加它们,我在Chrome中将时间缩短到85毫秒,在IE7中缩短到450毫秒! ! 你们真棒! 我给了user1一个答案,因为那个更全面,使用片段并没有真正改变我在Chrome中的时间,在IE7中增加了大约20ms。 但我仍然感谢@Emre Erkan的回答,并将更频繁地利用:)

最快的将是这样的:

 var oldTable = document.getElementById('example'), newTable = oldTable.cloneNode(true); for(var i = 0; i < json_example.length; i++){ var tr = document.createElement('tr'); for(var j = 0; j < json_example[i].length; j++){ var td = document.createElement('td'); td.appendChild(document.createTextNode(json_example[i][j])); tr.appendChild(td); } newTable.appendChild(tr); } oldTable.parentNode.replaceChild(newTable, oldTable); 

并且应该在几毫秒内运行。 下面是一个例子: http : //jsfiddle.net/Paulpro/YhQEC/它创建了200个表行,每行包含10个td。

您希望使用元素而不是字符串追加,但在创建整个结构之前,您不希望向DOM追加任何内容(以避免循环中的重排)。 因此,您可以克隆原始表并附加到克隆,然后在循环完成后插入克隆。

通过避免jQuery并直接与DOM交互,您还可以获得相当快的速度。

您的代码可能如下所示:

 var oldTable = document.getElementById('content_table'), newTable = oldTable.cloneNode(true), tr, td; for(var i = 0; i < entries.alumnus.length.length; i++){ tr = document.createElement('tr'); tr.id = 'entry' + i; tr.className = 'entry'; if(entries.alumnus[i].title){ td = document.createElement('td'); td.id = 'title' + i; td.className = 'cell'; var span = document.createElement('span'); span.className = 'content'; span.appendChild(document.createTextNode(entries.alumnus[i].title); td.appendChild(span); tr.appendChild(td); tr.appendChild(createFiller(filler)); } // REST OF ELEMENTS newTable.appendChild(tr); } oldTable.parentNode.replaceChild(newTable, oldTable); function createFiller(filler){ var td = document.createElement('td'); td.style.width = '5%'; td.appendChild(document.createTextNode(filler); return td; } 

我建议你使用DocumentFragment并使用原生的javascript进行这种大规模的DOM操作。 我准备了一个例子,你可以在这里查看 。

 var fragment = document.createDocumentFragment(), tr, td, i, il, key; for(i=0,il=data.length;i 

我认为这是完成这项工作的最快方式。

最重要的是从dom创建整个表格内容然后插入到表格中。 这个镀铬在大约3到5毫秒后结束:

 function createTableFromData(data) { var tableHtml = ''; var currentRowHtml; for (var i = 0, length = data.length; i < length; i++) { currentRowHtml = '' + data[i].join('') + ''; tableHtml += currentRowHtml; } return tableHtml; } var textToAppend= createTableFromData(yourData); $('#myTable').append(textToAppend); 

如果您从服务器获得了一个validation字符串JSON,并且该结构可靠地是一个字符串数组数组,则下面将允许您避免使用JSON解析,而是使用一系列常规表达式操作替换HTML生成在使用本机缓冲区的本机代码中实现。 这应该完全避免一次解析并用k,O(n)缓冲区副本替换任何花费O(n ** 2)的缓冲区副本以获得常数k。

 var jsonContent = ' [ [ "foo", "bar", "[baz\\"boo\\n]" ], ["1","2" , "3"] ] '; var repls = { // Equivalent inside a JSON string. ',': "\\u002b", '[': "\\u005b", ']': "\\u005d" }; var inStr = false; // True if the char matched below is in a string. // Make sure that all '[', ']', and ',' chars in JSON content are // actual JSON punctuation by re-encoding those that appear in strings. jsonContent = jsonContent.replace(/[\",\[\]]|\\./g, function (m) { if (m.length === 1) { if (m === '"') { inStr = !inStr; } else if (inStr) { return repls[m]; } } return m; }); // Prevent XSS. jsonContent = jsonContent.replace(/&/g, "&") .replace(/") html = html.replace(/]\s*$/g, "") // Introduce row boundaries. html = html.replace(/\],?/g, "") html = html.replace(/\[/g, "") // Introduce cell boundaries. html = html.replace(/,/g, "") // Decode escape sequences. var jsEscs = { '\\n': '\n', '\\f': '\f', '\\r': '\r', '\\t': '\t', '\\v': '\x0c', '\\b': '\b' }; html = html.replace(/\\(?:[^u]|u[0-9A-Fa-f]{4})/g, function (m) { if (m.length == 2) { // Second branch handles '\\"' -> '"' return jsEscs[m] || m.substring(1); } return String.fromCharCode(parseInt(m.substring(2), 16)); }); // Copy and paste with the below to see the literal content and the table. var pre = document.createElement('pre'); pre.appendChild(document.createTextNode(html)); document.body.appendChild(pre); var div = document.createElement('div'); div.innerHTML = html; document.body.appendChild(div); 

这绝对是可行的。 我不认为字符串连接是要走的路。 通常,当它们没有连接到主DOM时,创建元素并操纵它们似乎更快; 因此,首先创建整个表然后添加它。在简单的JavaScript中我认为下面的代码基本上是你想要实现的..

  //mock up the data (this will come from you AJAX call).. var data = []; for(var i = 0; i < 200; i++){ var rowData = []; for(var j = 0; j < 10; j++){ rowData.push("This is a string value"); } data.push(rowData); } //create table.. var table = document.createElement("table"); for(var i = 0; i < data.length; i++){ var rowData = data[i]; var row = document.createElement("tr"); for(var j = 0; j < rowData.length; j++){ var cell = document.createElement("td"); cell.innerHTML = rowData[j]; row.appendChild(cell); } table.appendChild(row); } //finally append the whole thing.. document.body.appendChild(table); 

当我将它粘贴到Safari中的控制台时,它会在<1秒内运行,所以你应该没问题。