Подтвердить что ты не робот

Создание таблицы HTML на лету с помощью jQuery

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

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

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

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") ;
4b9b3361

Ответ 1

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

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 в вашем script, если вы используете jQuery, вы можете предоставить мой Простые шаблоны - в попытке. Это упрощает процесс, резко сокращая количество конкатенаций, которые вы должны выполнить. Он работает очень хорошо, тоже после того, как я недавно сделал некоторые рефакторинг, что привело к довольно большому увеличению скорости. Вот пример (без выполнения всей вашей работы!):

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

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

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

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

Ответ 7

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

Ответ 8

Вы можете вставлять таблицу в 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") ;