PWAアプリ化した場合でもそうなんですが、スマホをロックしたり自動で消灯した際、SetTimeoutの処理は一旦停止されます。その後画面を復帰させると、SetTimeoutの処理が再度復活します。
つまり、簡易ストップウォッチ機能とか、何かしらの時間測定をJS側で行っていると、スマホがスリープしていた時間はカウントされない場合があります。
今回はこの対策として、SetTimeout処理の中でスリープによってズレた時間を自動補正します。
HTMLには以下のように書いておきます。
1 2 3 |
<div id="watch" class="mx-auto text-center h1 text-monospace">00:00:00</div> <!-- スマホのスリープなどで時間がずれた時用の記録用 --> <span id="last_check" style="display:none;"></span> |
SetTimeoutの中で、最終チェック時の経過時間からズレが5秒以上になったら自動的にズレた分を経過時間に追加します。(jQuery利用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<script type="text/javascript"> $(function(){ "use strict"; // タイムカウント $(window).on('load', function(){ let watch = null; if($("#watch").length){ // 1秒ごとに秒数カウントアップ watch = setInterval(panda, 1000); }; }); let panda = function() { // 経過時間をトータル秒数で取得 let init_time = $("#watch").html().replace(/\r?\n|\s/g,"");; let total_sec = (parseInt(init_time.slice(0,2)) * 3600) + (parseInt(init_time.slice(3,5)) * 60 ) + parseInt(init_time.slice(6,8)); let now = Date.now(); let last_check = $("#last_check").text(); // ズレをマイクロ秒で取得 let diff = now - parseInt(last_check, 10); // ズレが5秒以上なら経過時間にズレた時間を追加 if ( diff && diff > 5000){ total_sec += diff/1000; } else{ total_sec += 1; } let byo = Math.floor(total_sec) % 60; let fun = Math.floor(total_sec / 60) % 60; let ji = Math.floor(total_sec / 3600) % 60; // 時間の表示を更新 $("#watch").text( ('00' + ji).slice(-2) + ":" + ('00' + fun).slice(-2) + ":" + ('00' + byo).slice(-2) ); // 現在時間を記録しておく $("#last_check").text(now); } </script> |
今回は簡易的なストップウォッチなのでこのような方法でやりましたが、欠点としては、ズレ補正の度に、若干(数ミリ秒ずつ)のずれが発生する可能性があります。
正確にズレ補正を行う場合は、計測スタート時に、開始時刻をミリ秒で記録しておくのが一番確実でしょう。