5

Trong một phương thức chạy trong 10 giây để thêm một số phần tử vào html, gif động không chuyển động chút nào, tạo cảm giác rằng trang web bị kẹt. Bất kỳ cách nào xung quanh điều này.Ảnh động không di chuyển trong khi gọi phương thức javascript dài

Ví dụ mã:

 
    $('#button).click(function() { 
     showAnimatedGif(); 
     longRunningMethod();  
     hideAnimatedGif(); 
    }); 

Một cách để khắc này là để chia tay các phương pháp chạy dài trong nhiều bước và hiệu ứng động theo cách này, nhưng sau đó bạn phải viết mã của bạn theo cách này cho từng phương pháp chạy dài.

Tự hỏi liệu có cách nào khác để thực hiện việc này không?

+0

[Đừng làm vậy rồi] (http://www.jargon.net/jargonfile/d/Dontdothatthen.html). Bạn biết rằng JavaScript không phải là đa luồng, phải không? –

+0

Tôi biết điều đó, nhưng phải có những cách để thực hiện điều này. – mrjohn

+0

'showAnimatedGif()' đang làm gì? 'LongRunningMethod()' đang làm gì? Bạn có thể đăng thêm mã không? – karim79

Trả lời

6

Cách duy nhất để đảm bảo rằng hoạt ảnh thực sự xảy ra là dành cho longRunningMethod để mang lại cho trình duyệt theo định kỳ. Việc chuỗi hiển thị giao diện người dùng bị chặn không phổ biến trên chuỗi JavaScript, do đó các thay đổi bạn thực hiện đối với DOM không được hiển thị cho đến lần tiếp theo khi chuỗi JavaScript tạo ra. Bạn có thể kiếm tiền bằng cách gọi setTimeout với thời gian chờ là 0 (sẽ dài hơn 0ms   — rõ ràng là   — trên hầu hết các lần triển khai trình duyệt; nhiều kẹp có giá trị ít nhất 4ms và có thể nhiều nhất là 10ms).

Ví dụ: Dưới đây là một kịch bản có thêm 500 divs, nhưng cung cấp cho các trình duyệt không có cơ hội thể hiện những công việc cơ bản dở dang hoặc (thường) động bất cứ điều gì:

jQuery(function($) { 

    $("#btnGo").click(function() { 
    var n; 

    display("Loading..."); 

    for (n = 0; n < 500; ++n) { 
     $("<div/>").html("Div #" + n).appendTo(document.body); 
    } 

    display("Done loading"); 

    function display(msg) { 
     $("<p/>").html(msg).appendTo(document.body); 
    } 
    }); 

});​ 

Live example * Example with spinner graphic

Như bạn có thể thấy, nó không bao giờ sản lượng, và vì vậy khi bạn nhấp vào nút, trang bị đóng băng trong một khoảnh khắc, và sau đó tất cả 500 div và thông báo xuất hiện.

Contrast với đầu kia của quang phổ, trong đó sản lượng giữa mỗi div:

jQuery(function($) { 

    $("#btnGo").click(function() { 
    display("Loading..."); 

    addDivs(0, 500, function() { 
     display("Done loading"); 
    }); 

    function addDivs(current, max, callback) { 
     if (current < max) { 
     $("<div/>").html("Div #" + current).appendTo(document.body); 
     setTimeout(function() { 
      addDivs(current + 1, max, callback); 
     }, 0); 
     } 
     else { 
     callback(); 
     } 
    } 

    function display(msg) { 
     $("<p/>").html(msg).appendTo(document.body); 
    } 
    }); 

});​ 

Live example * Example with spinner graphic

Kể từ đó sản lượng, bạn sẽ nhìn thấy công việc được tiến hành.

Bạn có thể nhận thấy rằng tập lệnh thứ hai mất nhiều thời gian hơn, có thể lâu hơn, trong thời gian thực để đạt được kết quả tương tự. Điều này là do sản lượng mất thời gian, cũng như trình duyệt cập nhật màn hình. Trong thực tế, bạn sẽ muốn tìm sự cân bằng giữa ví dụ đầu tiên và thứ hai   — thứ gì đó mang lại đủ thường xuyên để hiển thị tiến trình, nhưng không quá thường xuyên quá trình mất một thời gian dài không cần thiết để hoàn thành.

+0

cuộc gọi chính xác tới setTimeout trông như thế nào? – mrjohn

+0

@mrjohn: Đã thêm một ví dụ có và không có. –

+0

Điểm thú vị về việc tìm số dư phù hợp. Tôi tự hỏi nếu nó có thể thực hiện khả năng của trình duyệt trước khi năng suất để có được kết quả tốt nhất. Loại như FPS trong đồ họa. –

0

Nếu phương pháp chạy dài của bạn đang thực hiện cuộc gọi ajax đồng bộ. Sử dụng tùy chọn không đồng bộ trên phương thức mở.

xmlHttp.open('POST', ajaxurl, true); 

Điều này sẽ cho phép đồ họa quay của bạn quay.

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