簡體   English   中英

倒數計時器問題

[英]Count Down Timer Issue

我正在用PHP創建一個定時測試產品。 我在保持考試時間正確方面面臨一個問題。 考試開始后,只要我在同一屏幕上,計時器都可以正常工作。 但是,當我在測試進行中打開其他屏幕時(例如,持續10分鍾),並且在一段時間后返回測試時,計時器顯示錯誤的時間,並且似乎顯示前10分鍾僅消耗了2分鍾的測試時間。

只想知道為什么當我在進行測試時離開屏幕並在一段時間后返回時,測試計時器的這種不穩定行為。

有人可以幫我嗎?

PHP代碼

<?php
/*Timer Code*/
        $dateFormat = "d F Y -- g:i a";
        $targetDate = time() + (240*60);//Change the 240 to however many minutes you want to countdown
        $actualDate = time();
        $secondsDiff = $targetDate - $actualDate;
        $remainingDay     = floor($secondsDiff/60/60/24);
        $remainingHour    = floor(($secondsDiff-($remainingDay*60*60*24))/60/60);
        $remainingMinutes = floor(($secondsDiff-($remainingDay*60*60*24)-($remainingHour*60*60))/60);
        $remainingSeconds = floor(($secondsDiff-($remainingDay*60*60*24)-($remainingHour*60*60))-($remainingMinutes*60));
        $actualDateDisplay = date($dateFormat,$actualDate);
        $targetDateDisplay = date($dateFormat,$targetDate);
?>

的JavaScript

/*Timer Code*/
  var days = <?php echo $remainingDay; ?>  
  var hours = <?php echo $remainingHour; ?>  
  var minutes = <?php echo $remainingMinutes; ?>  
  var seconds = <?php echo $remainingSeconds; ?> 

function setCountDown ()
{
  seconds--;
  if (seconds < 0){
      minutes--;
      seconds = 59
  }
  if (minutes < 0){
      hours--;
      minutes = 59
  }
  if (hours < 0){
      days--;
      hours = 23
  }
  document.getElementById("remain").innerHTML = "Time "+hours+" H : "+minutes+" M : "+seconds+" S";
  SD=window.setTimeout( "setCountDown()", 1000 );
  if (hours == '0' && minutes == '00' && seconds == '00') 
  { 
      seconds = "00"; window.clearTimeout(SD);
      timeStatus = 1;
      var response = window.alert("Time is up. Press OK to continue."); // change timeout message as required         
  } } // here is the end of setCountDown

這對我來說適用於列出的更改:

PHP:

<?php
/*Timer Code*/
        $dateFormat = "d F Y -- g:i a";
        $targetDate = time() + (240*60);//Change the 240 to however many minutes you want to countdown
        $actualDate = time();
        $secondsDiff = $targetDate - $actualDate;
        $remainingDay     = floor($secondsDiff/60/60/24);
        $remainingHour    = floor(($secondsDiff-($remainingDay*60*60*24))/60/60);
        $remainingMinutes = floor(($secondsDiff-($remainingDay*60*60*24)-($remainingHour*60*60))/60);
        $remainingSeconds = floor(($secondsDiff-($remainingDay*60*60*24)-($remainingHour*60*60))-($remainingMinutes*60));
        $actualDateDisplay = date($dateFormat,$actualDate);
        $targetDateDisplay = date($dateFormat,$targetDate);
?>
  • PHP的開放應該是

JavaScript:

/*Timer Code*/
  var days = 0;
  var hours = 4;
  var minutes = 0;
  var seconds = 0;

  setCountDown();

function setCountDown ()
{
  seconds--;
  if (seconds < 0){
      minutes--;
      seconds = 59
  }
  if (minutes < 0){
      hours--;
      minutes = 59
  }
  if (hours < 0){
      days--;
      hours = 23
  }
  if (hours == '0' && minutes == '00' && seconds == '00') 
  { 
      seconds = "00"; 
      window.clearTimeout(SD);
      timeStatus = 1;
      var response = window.alert("Time is up. Press OK to continue."); // change timeout message as required         
  } 
  console.log(days+'/'+hours+'/'+minutes+'/'+seconds);
  SD=setTimeout(setCountDown, 1000);
}
  • setCountDown缺少它的右括號
  • 應該僅使用函數名稱來調用setTimeout。 名稱將返回的值傳遞給setTimeout而不是函數本身后,使用()進行調用。 (最后一點與您的問題無關,因為您使用引號引起了函數調用)
  • 在檢查是否為0之后,確實應該重新調用該函數。

對於更精確的計時器系統,請考慮使用服務器和用戶計算機上的時間戳,而不是可以操縱的變量。 然后,您可以從用戶計算機上連續獲取當前時間,以查看已過去了多少時間。

當不在前台運行時,JavaScript不會總是處理計時器滴答,因此這就是為什么您會變慢。

如果您會:

  • 在JS中使用目標期限,您可以將其轉換為每次處理計時器事件時的剩余時間。 這樣,它將始終與實際截止日期相關。
  • 時常從服務器刷新截止日期信息(不是每秒刷新一次,而是每5分鍾刷新一次)。 這意味着您必須在服務器端使用某種持久性,例如會話作用域變量,該變量的截止日期可以用來返回剩余的秒數。
  • 在服務器端驗證提交的答案不會在截止日期后發生(如果有人篡改了客戶端)。 同樣,您將需要一些會話范圍用法來實現此目的。

我將不提供第二個或第三個想法的代碼,但是下面是適合第一個想法的代碼(可能足以滿足您的目的?):

 /*Timer Code*/ var totalSeconds = 240*60; //<?php echo 240*60; ?> var deadlineMillis = Date.now() + totalSeconds * 1000; function setCountDown () { var secondsRemaining = Math.max(0, Math.round((deadlineMillis - Date.now()) / 1000)), minutes = Math.floor(secondsRemaining / 60), hours = Math.floor(minutes / 60), days = Math.floor(hours / 24); hours = hours % 24; minutes = ('0' + (minutes % 60)).substr(-2); seconds = ('0' + (secondsRemaining % 60)).substr(-2); document.getElementById("remain").textContent = "Time "+hours+" H : "+minutes+" M : "+seconds+" S"; if (secondsRemaining === 0) { timeStatus = 1; alert("Time is up. Press OK to continue."); // change timeout message as required return; } setTimeout(setCountDown, 1000); } setCountDown(); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="remain"></div> 

用PHP生成的值替換240*60

大多數現代瀏覽器故意將較低的優先級放在不活動的標簽/窗口上。 因此,計時器將變慢。 因此,您所面對的並不是不穩定的行為。 這是設計提高瀏覽器性能的方法。

https://developers.google.com/web/updates/2017/03/background_tabs#budget-based_background_timer_throttling

https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Timeouts_in_inactive_tabs_throttled_to_ > 1000毫秒

解決方案:使用網絡工作者

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM