Создание HTML-таблицы на лету с использованием jQuery - PullRequest
21 голосов
/ 19 сентября 2008

Ниже приведен код, который я использую для создания таблицы HTML на лету (с использованием данных JSON, полученных с сервера).

Я отображаю анимированное изображение Pleasewait (.GIF) во время загрузки данных. Тем не менее, изображение останавливается, пока функция JavaScript строит таблицу. Сначала я был просто счастлив сделать это (показать таблицу), я думаю, теперь мне нужно работать над эффективностью. По крайней мере, мне нужно, чтобы анимация не зависала. Я могу перейти к статическому экрану «Загрузка», но я бы предпочел, чтобы этот метод работал.

Предложения для моего дисплея, пожалуйста, подождите? А эффективность? Возможно, лучший способ построить таблицу? Или, может быть, не таблица, а какой-то другой «стол», такой как display

var t = eval( "(" + request + ")" ) ;
var myTable = '' ;
myTable += '<table id="myTable" cellspacing=0 cellpadding=2 border=1>' ;
myTable +=  "<thead>" ;
myTable +=   "<tr>";
for (var i = 0; i < t.hdrs.length; i++) {
    myTable +=    "<th>"     + header +       "</th>";
}
myTable +=   "</tr>" ;
myTable +=  "</thead>" ;
myTable +=  "<tbody>" ;

for (var i = 0; i < t.data.length; i++) {
    myTable +=    '<tr>';
    for (var j = 0; j < t.hdrs.length; j++) {
        myTable += '<td>';
        if (t.data[i][t.hdrs[j]] == "") {
            myTable += "&nbsp;" ;
        }
        else {
            myTable += t.data[i][t.hdrs[j]] ;
        }
        myTable += "</td>";
    }
    myTable +=    "</tr>";
}
myTable +=  "</tbody>" ;
myTable += "</table>" ;

$("#result").append(myTable) ;
$("#PleaseWaitGraphic").addClass("hide");
$(".rslt").removeClass("hide") ;

Ответы [ 8 ]

26 голосов
/ 20 сентября 2008

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

function doSomething (progressFn [, additional arguments]) {
    // Initialize a few things here...
    (function () {
        // Do a little bit of work here...
        if (continuation condition) {
            // Inform the application of the progress
            progressFn(value, total);
            // Process next chunk
            setTimeout(arguments.callee, 0);
        }
    })();
}

Что касается упрощения создания HTML в вашем скрипте, если вы используете jQuery, вы можете попробовать мой плагин Simple Templates . Это упрощает процесс, резко сокращая количество конкатенаций, которые вам нужно сделать. Он работает довольно хорошо, даже после того, как я недавно провел некоторый рефакторинг, который привел к довольно большому увеличению скорости . Вот пример (без выполнения всей работы за вас!):

var t = eval('(' + request + ')') ;
var templates = {
    tr : '<tr>#{row}</tr>',
    th : '<th>#{header}</th>',
    td : '<td>#{cell}</td>'
};
var table = '<table><thead><tr>';
$.each(t.hdrs, function (key, val) {
    table += $.tmpl(templates.th, {header: val});
});
...
11 голосов
/ 19 сентября 2008

Я использовал JTemplates , чтобы выполнить то, что вы описываете. У Дейва Уорда есть пример в его блоге здесь . Основным преимуществом JTemplates является то, что ваш html не вплетен в ваш javascript. Вы пишете шаблон и вызываете две функции, чтобы jTemplate собирал HTML из вашего шаблона и вашего json.

3 голосов
/ 20 сентября 2008

Использование innerHTML определенно может быть намного быстрее, чем использование jQuery HTML-to-DOM-ifier, который использует innerHTML, но выполняет большую обработку входных данных.

Я бы предложил проверить chain.js как способ быстрого построения таблиц и других повторяющихся структур данных из объектов JavaScript. Это действительно легкий, умный плагин для привязки данных для jQuery.

3 голосов
/ 19 сентября 2008

Что вы делаете, это строите строку, а затем сразу разбираете ее при вставке. Как насчет создания фактического элемента таблицы (т. Е. $("<table>")) и последующего добавления к нему каждой строки? К тому времени, когда вы на самом деле вставите его в страницу, все DOM-узлы будут уже созданы, поэтому это не должно быть таким большим ударом.

0 голосов
/ 06 декабря 2008

Поиск в Интернете JavaScript и StringBuilder. Как только у вас будет построитель строк JavaScript, убедитесь, что вы используете метод .append для каждой конкатенации. То есть вы не хотите иметь никаких + конкатенаций. После этого выполните поиск JavaScript и replacehtml. Используйте эту функцию вместо innerHTML.

0 голосов
/ 19 сентября 2008

Мой опыт показывает, что есть две отдельные задержки. Один объединяет все эти строки вместе. Другой случай, когда браузер пытается отобразить строку. Как правило, именно IE имеет наибольшую проблему с зависаниями пользовательского интерфейса, отчасти потому, что он намного медленнее запускает JavaScript. Это должно стать лучше в IE8.

В вашем случае я бы предложил разбить операцию на шаги. Скажем, для таблицы из 100 строк вы сначала создаете правильную таблицу из 10 строк. Затем вы выводите это на экран и используете setTimeout, чтобы вернуть управление браузеру, чтобы пользовательский интерфейс прекратил блокировку. Когда setTimeout возвращается, вы делаете следующие 10 строк и т. Д.

Создание таблицы с использованием DOM, безусловно, "чище", как говорили другие. Тем не менее, есть высокая цена, чтобы заплатить с точки зрения производительности. См. Отличную статью quirksmode на эту тему, в которой есть некоторые тесты, которые вы можете запустить самостоятельно.

Короче говоря, innerHTML намного, намного быстрее, чем DOM, даже на современных движках JS.

0 голосов
/ 19 сентября 2008

Вы можете вставлять таблицу в DOM по крупицам. Честно говоря, я не совсем уверен, поможет ли это вашей проблеме, но стоит попробовать. Я бы сделал это примерно так (непроверенный код, можно было бы уточнить еще немного):

$("#result").append('<table id="myTable" cellspacing=0 cellpadding=2 border=1></table>');
$('#myTable').append('<thead><tr></tr></thead>');
$('#myTable').append('<tbody></tbody>');

for (var i = 0; i < t.hdrs.length; i++) { 
    $('#myTable thead tr').append('<th>'+header+'</th>');
}

for (var i = 0; i < t.data.length; i++) { 
 myTr =    '<tr>';
 for (var j = 0; j < t.hdrs.length; j++) { 
  myTr += '<td>';
  if (t.data[i][t.hdrs[j]] == "") { 
   myTr += "&nbsp;" ; 
  }
  else { 
   myTr += t.data[i][t.hdrs[j]] ; 
  }
  myTr += "</td>";
  }
 myTr +=    "</tr>";
 $('#myTable tbody').append(myTr);
}

$("#PleaseWaitGraphic").addClass("hide");
$(".rslt").removeClass("hide") ;
0 голосов
/ 19 сентября 2008

Для начала, посмотрите flydom и его варианты, они очень помогут. Не могли бы вы дать больше контекста? Если это не в onload и просто вставлено в страницу, просто завернув все это в $ (function () {/ * code * /}), вы, вероятно, очистите все, с чем у вас проблемы. Встроенный JS выполняется немедленно, что означает цикл для таблицы. onload - это событие, которое по сути «отсоединено».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...