2008-09-19 54 views
21

Dưới đây là mã tôi sử dụng để tạo bảng HTML khi đang chạy (sử dụng dữ liệu JSON nhận được từ máy chủ).Tạo bảng HTML khi đang chạy bằng cách sử dụng jQuery

Tôi hiển thị hình ảnh vui nhộn hoạt hình (.gif) trong khi dữ liệu đang tải. Tuy nhiên, đồ họa bị đóng băng trong khi hàm JavaScript đang xây dựng bảng. Lúc đầu, tôi rất vui khi thực hiện điều này (hiển thị bảng), tôi đoán bây giờ tôi cần phải làm việc hiệu quả. Ít nhất thì tôi cũng cần phải ngừng hoạt hình bằng cách đóng băng. Tôi có thể đi đến màn hình "Đang tải" tĩnh, nhưng tôi muốn làm phương pháp này hoạt động.

Gợi ý cho màn hình xin vui lòng của tôi? Và hiệu quả? Có thể một cách tốt hơn để xây dựng bảng? Hoặc có thể không phải bảng, nhưng một số "bảng" khác như hiển thị

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") ; 
+0

Bạn muốn tạo bao nhiêu cột và hàng trong mã này? –

Trả lời

26

Về cơ bản, bạn muốn thiết lập các vòng lặp của mình để chúng sinh ra các chủ đề khác thường xuyên.Dưới đây là một số mã ví dụ từ this article về chủ đề chạy CPU hoạt động chuyên sâu mà không đóng băng UI của bạn:

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

Theo như đơn giản hóa việc sản xuất của HTML trong kịch bản của bạn, nếu bạn đang sử dụng jQuery, bạn có thể cung cấp cho tôi Simple Templates plug-in một thử. Nó xử lý quá trình bằng cách cắt giảm đáng kể số lượng các kết nối bạn phải làm. Nó thực hiện khá tốt, quá sau khi tôi gần đây đã làm một số refactoring mà kết quả là khá lớn speed increase. Dưới đây là một ví dụ (mà không làm tất cả công việc dành cho bạn!):

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

Cảm ơn, tôi đánh giá cao plugin Simple Templates. FYI, ứng dụng liên kết tăng tốc của bạn bị hỏng. Tôi nhận được một số lỗi JavaScript khi tôi cố gắng chạy bất kỳ thử nghiệm nào. – Rich

+0

Cảm ơn bạn đã cho tôi biết, Rich. Vấn đề là các thử nghiệm giả định một phiên bản cũ hơn của jQuery. Phiên bản mới hơn có trong phần chân trang đã phá vỡ cách tôi đã viết các plugin. Nó đã được sửa ngay bây giờ, nếu bạn muốn thử lại. –

+0

Trang web của bạn bị hỏng. Bạn có nhớ cung cấp một ví dụ hoàn chỉnh? –

3

Những gì bạn đang làm là tạo chuỗi và sau đó phân tích cú pháp tất cả cùng một lúc khi chèn. Điều gì về việc tạo một phần tử bảng thực tế (tức là $("<table>")), sau đó thêm từng hàng vào nó? Bởi thời gian bạn thực sự chèn nó vào trang, các nút DOM tất cả sẽ được xây dựng, do đó, nó không nên là một hit lớn.

0

Để bắt đầu, hãy xem flydom và các biến thể của nó, chúng sẽ giúp chấm dứt. Bạn có thể đưa ra nhiều ngữ cảnh hơn không? Nếu đây không phải là onload và chỉ dán trong trang, chỉ cần gói toàn bộ điều trong $ (function() {/ * code * /}) có thể sẽ dọn sạch mọi thứ bạn đang gặp vấn đề. Inline JS được thực hiện ngay lập tức, có nghĩa là vòng lặp cho bảng. onload là một sự kiện và về cơ bản là 'tách rời'.

-2

Bạn có thể chèn bảng vào bit DOM từng chút một. Thành thật mà nói tôi không hoàn toàn chắc chắn nếu điều này sẽ giúp đỡ với vấn đề của bạn, nhưng nó có giá trị một thử. Tôi sẽ làm như thế này (mã chưa được kiểm tra, có thể tinh chỉnh thêm một số chi tiết):

$("#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

Kinh nghiệm của tôi là có hai sự chậm trễ riêng biệt. Một là nối tất cả các chuỗi lại với nhau. Cách khác là khi trình duyệt thực sự cố gắng hiển thị chuỗi. Thông thường, đó là IE có nhiều rắc rối nhất với giao diện người dùng bị đóng băng, một phần vì nó chạy chậm hơn rất nhiều khi chạy javascript. Điều này sẽ tốt hơn trong IE8.

Điều tôi đề nghị trong trường hợp của bạn là phá vỡ hoạt động thành các bước. Nói cho một bảng hàng 100, trước tiên bạn tạo ra một bảng 10 hàng hợp lệ. Sau đó, bạn xuất ra màn hình và sử dụng setTimeout để điều khiển trở lại trình duyệt để giao diện người dùng dừng chặn. Khi setTimeout quay trở lại, bạn thực hiện 10 hàng tiếp theo, v.v.

Tạo bảng bằng DOM chắc chắn là "sạch hơn", như những người khác đã nói. Tuy nhiên, có một mức giá cao để trả về hiệu suất. Xem bài viết tuyệt vời quirksmode về chủ đề này, trong đó có một số điểm chuẩn bạn có thể tự chạy.

Ngắn câu chuyện ngắn, innerHTML nhanh hơn nhiều so với DOM, ngay cả trên các công cụ JS hiện đại.

+0

Không ai đề xuất tạo bảng bằng DOM, vì vậy tham chiếu của bạn không thể áp dụng. Chèn nội dung với innerHTML tạo các nút DOM. Đề cập đến thực tế này không phải là điều tương tự như đề xuất việc sử dụng createElement. – Jim

11

Tôi đã sử dụng JTemplates để hoàn thành những gì bạn mô tả. Dave Ward có một ví dụ trên blog của mình here. Lợi ích chính của JTemplates là html của bạn không được chèn vào javascript của bạn. Bạn viết một mẫu và gọi hai hàm để có jTemplate xây dựng html từ mẫu của bạn và json của bạn.

+1

Chắc chắn đồng ý ở đây, việc tạo mẫu site của khách hàng là cách tốt nhất để bạn có thể tạo các phần tử HTML từ một nguồn dữ liệu. –

3

Sử dụng innerHTML chắc chắn có thể nhanh hơn nhiều so với sử dụng HTML-to-DOM-ifier jQuery, trong đó sử dụng innerHTML nhưng hiện rất nhiều xử lý trên đầu vào.

Tôi khuyên bạn nên kiểm tra chain.js như một cách để nhanh chóng xây dựng các bảng và các cấu trúc dữ liệu lặp lại khác từ các đối tượng JavaScript. Đó là một plugin dữ liệu thông minh rất nhẹ, thông minh dành cho jQuery.

0

Tìm kiếm trên web cho JavaScript và StringBuilder. Khi bạn có trình tạo chuỗi JavaScript, hãy đảm bảo bạn sử dụng phương thức .append cho mỗi lần ghép nối. Tức là, bạn không muốn có bất kỳ kết nối nào +. Sau đó, tìm kiếm JavaScript và replacehtml. Sử dụng chức năng này thay vì innerHTML.

Các vấn đề liên quan