2012-04-18 29 views
5

Như đã đề cập trong tiêu đề tôi đang cố gắng tạo một nhịp dựa trên jQuery/JavaScript cùng với thẻ HTML <audio /> để phát âm thanh.HTML5/jQuery metronome - các vấn đề về hiệu năng

Nó hoạt động "okay", nhưng có vẻ như tôi là phương pháp setInterval không hoạt động chính xác đủ. Tôi tìm kiếm một số chủ đề ở đây, nhưng đối với tôi mới cho cả jQuery và JavaScript và tôi đã không tìm thấy một giải pháp làm việc. Tương tự cho "mở tab mới và setInterval dừng hoặc chậm" - vấn đề. Tôi đã cố gắng để ngăn chặn điều đó với stop(true,true) nhưng nó không hoạt động như tôi mong đợi.

Tôi muốn nhịp chạy "ở chế độ nền" mà không thay đổi tiến độ khi mở tab mới và thực hiện điều gì đó ở đó. Ngoài ra tôi muốn một nhịp chính xác cho chắc;)

Dưới đây là môi trường thử nghiệm của tôi nằm: http://nie-wieder.net/metronom/test.html

Tại thời điểm này, JS-Code và HTML markup là tất cả trong nguồn test.html, vì vậy bạn có thể tìm ở đó .

Ngoài ra, đây là liên quan (như tôi nghĩ) js-code tôi sử dụng:

$(document).ready(function() { 

    //vars 
    var intervalReference = 0; 
    var currentCount  = 1;  
    var countIncrement  = .5;  
    var smin = 10; 
    var smax =240; 
    var svalue = 120; 

    //soundchkbox 
    $(".sndchck").attr("disabled", true); 

    //preload sound 
    $.ajax({ 
     url: "snd/tick.ogg", 
     success: function() { 
      $(".sndchck").removeAttr("disabled"); 
     } 
    }); 

    // tick event 
    var met = $("#bpm").slider({ 
      value: 120, 
      min: smin, 
      max: smax, 
      step: 1, 
      change: function(event, ui) { 
       var delay = (1000*60/ui.value)/2 
       clearInterval(intervalReference); 

       //seems to be the Problem for me 
       intervalReference = setInterval(function(){ 
        var $cur_sd = $('#sub_div_'+currentCount); 
        $cur_sd 
        .stop(true,true) 
        .animate({opacity: 1},15, 
           function() { 
           //Play HTML5 Sound 
           if($('#sound_check:checked').val()){ 
            $('#tick') 
            .stop(true,true) 
            .trigger("play"); 
           } 
            $(this). 
            stop(true,true). 
            animate({opacity:0}); 
           } 
        ); 
        currentCount += countIncrement; 
        if(currentCount > 4.5) currentCount = 1 
       }, delay); 
       createMusicTag(ui); 
      } 
     }); 
}); 

Bất kỳ trợ giúp sẽ là tuyệt vời, tôi hết ý tưởng cho bây giờ.

Trả lời

5

setInterval không chính xác. những gì bạn có thể thử làm được cái gì đó như:

var timestamp = (new Date()).getTime(); 
function run() { 

    var now = (new Date()).getTime(); 

    if(now - timestamp >= 1000) { 
     console.log('tick'); 
     timestamp = now; 
    } 

    setTimeout(run, 10); 
} 
run(); 

này sẽ (mỗi phần trăm của một giây) so sánh 'timestamp' với thời điểm hiện tại để xem nếu diff là một giây trở lên (độ lệch là 0,01 giây) và nếu đó là nhật ký 'đánh dấu' và đặt lại dấu thời gian hiện tại.

http://jsfiddle.net/rlemon/UqbwT/

Đây là phương pháp tốt nhất để một cái gì đó mà cần phải có thời gian chính xác (IMO).

Cập nhật: nếu bạn thay đổi cài đặt thời gian setTimeout ... bạn sẽ nhận được ít độ lệch. http://jsfiddle.net/rlemon/UqbwT/1/

Cập nhật thứ hai: Sau khi xem bài đăng này, tôi nghĩ rằng phải có cách chính xác hơn để sử dụng bộ tính giờ trong javascript .. vì vậy với một chút nghiên cứu tôi đã xem qua this bài viết. Tôi đề nghị bạn đọc nó.

+0

trước hết là cảm ơn câu trả lời rất nhanh của bạn. Tôi cập nhật fiddle của bạn ở đây: http://jsfiddle.net/ping/UqbwT/3/ để xem nếu cách tiếp cận của bạn làm việc cho tôi. Dường như nó không, ít nhất là trên macbook của tôi (firefox 11). Hoặc là nó chỉ cho tôi thấy những lags sau một thời gian? (đánh dấu cho thấy> 600 hoặc> 700 trong một thời gian). – Dominik

+0

có thể là một vấn đề với việc triển khai. nhưng về cơ bản ý tưởng vẫn đúng. Bạn không thể dựa vào các chức năng định thời của trình duyệt. chúng không chính xác và bạn ** sẽ ** thấy độ lệch. Thay vào đó, bạn muốn chạy một vòng lặp liên tục trong nền xem xét ngày tháng và thời gian thực và sử dụng nó để xác định xem một giây đã trôi qua chưa. – rlemon

+0

aye, bạn nói đúng, cảm ơn câu trả lời của bạn cho đến nay. Tôi nghĩ rằng tôi sẽ tiếp tục với giải pháp của bạn và tạo ra một ứng dụng java hoặc một cái gì đó cho những người muốn "nhiều hơn";) Cảm ơn bạn rất nhiều. Ít nhất bạn nói đúng, đó là một vấn đề triển khai và tôi nghĩ rằng tôi không thể làm nhiều hơn về nó. – Dominik

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