HTML:如何获取多个计时器组合

时间:2020-05-04 17:37:00

标签: javascript html user-input setinterval

我正在根据用户输入构建计时器。以下是代码应如何工作: 用户输入: 开启时间:30秒

关闭时间:10秒

套数:4

每组练习数:5

每组间隔:30s

通过上述用户输入,计时器将执行以下操作: Working Timer

希望这对应该做什么有意义。我目前正在尝试在两套装置之间实施其余的装置。有人知道我现在的代码如何实现这一目标吗? totalTime还已经包括了如果有帮助的话,集合之间其余时间的总和。

new ProcessBuilder("java", "-cp", "/path/to/package", "praktikum.Server");

var numsets = document.getElementById("userInput1");
var numex = document.getElementById("userInput2");
var numwork = document.getElementById("userInput3");
var numrest = document.getElementById("userInput4");
var numrestafterset = document.getElementById("userInput5");

var sets;
var OGtimeon;
var OGtimeoff;
var totalTime;
var timeRemaining;
var hasBeenStarted = false;  // Boolean value to test what time to use

var isTimeON = true;
var timeon;
var timeoff;
var timeonRemaining;
var timeoffRemaining;
var setsRemaining;
var OGsets;
var Prepare;
var OGExPS;
var OGTOASets;
var ExercisePS;
var RestAfterS;
var Intervals
var j = 0;
var ExercisesRemaining;
var RestRemaining;

// function sleep(milliseconds) { //function I found online to create a sleep function
//     const date = Date.now();
//     let currentDate = null;
//     do {
//       currentDate = Date.now();
//     } while (currentDate - date < milliseconds);
//   }

// function updateRest() {
//     if (RestAfterS > 0) {
//         interval3 = setInterval(RestCount, 1000);
//     }
//     else {
//         startTime();
//     }

// function RestCount() {
//     while (RestAfterS != 0) {
//         RestAfterS--;
//     }
//     j = 0;
// }

function updatePrep() {
    if  (hasBeenStarted == false) {
        Prepare = 5;
        interval2 = setInterval(PrepCount, 1000);
    }
    else {
        startTime();
    }
}


function PrepCount() {
    let seconds = parseFloat(Prepare) % 60;

    if (Prepare == 0) {
        clearInterval(interval2);
        startTime();
    }
    else {
        PWR.innerHTML = "Get Ready!";
        textarea.innerHTML = Prepare;
        console.log(Prepare);
        Prepare--;
    }
}



function startTime() {

    // Set values in code
    OGsets = numsets.value;
    OGtimeon = numwork.value;
    OGtimeoff = numrest.value;
    OGTOASets = numrestafterset.value;
    OGExPS = numex.value;
    

    timeon = (hasBeenStarted)? timeonRemaining : OGtimeon;
    timeoff = (hasBeenStarted)? timeoffRemaining : OGtimeoff;
    sets = (hasBeenStarted)? setsRemaining : OGsets;
    ExercisePS = (hasBeenStarted)? ExercisesRemaining : OGExPS;
    RestAfterS = (hasBeenStarted)? RestRemaining : OGTOASets;

    // How much time on timer
    // Var = (expression)? true : false this is basically an if statement
    totalTime = (hasBeenStarted)? timeRemaining : ((parseFloat(OGtimeon)*parseFloat(sets)*parseFloat(ExercisePS))+(parseFloat(OGTOASets)*(parseFloat(sets)-1))+(parseFloat(OGtimeoff)*(parseFloat(sets)*(parseFloat(ExercisePS)-1))));
    Intervals = ((parseFloat(sets)*parseFloat(ExercisePS))+((parseFloat(sets)-1))+((parseFloat(sets)*(parseFloat(ExercisePS)-1))));
    hasBeenStarted = true;
    

    // Start timer
    interval = setInterval(updateCountdown, 1000);
}



function updateCountdown() {
    IntervalsLeft.innerHTML = Intervals;
    setsLeft.innerHTML = sets;

    var minutes= Math.floor (parseFloat(totalTime) / 60);
    var seconds = parseFloat(totalTime) % 60;
    if (seconds < 10) {
        textareaRemaining.innerHTML = minutes + ":0" + seconds;
    } else {
        textareaRemaining.innerHTML = minutes + ":" + seconds;
    }

    // Update TimeON / Time OFF
    if(isTimeON){          
        PWR.innerHTML = "Work!";    
        textarea.innerHTML = timeon;
        timeon--;
        if(timeon == 0){
            isTimeON = false;
            timeon = OGtimeon;
            Intervals--;
            IntervalsLeft.innerHTML = Intervals;
        }
        
    }
    //BELOW IS THE AREA I AM STUCK ON

    else{
        
       textarea.innerHTML = timeoff;
       timeoff--;
       PWR.innerHTML = "Rest!";
       if(timeoff == 0){
            isTimeON = true;
            timeoff = OGtimeoff;
            j++;
            Intervals--;
            IntervalsLeft.innerHTML = Intervals;
            if (j == OGExPS) {
                sets--;
                //updateRest();
                j = 0;
            }
             
        }
    }
        if( totalTime == 0 ){
            clearTimeout(interval);
            hasBeenStarted = false;
            console.log(sets);
            sets--;
            setsLeft.innerHTML = sets;
            PWR.innerHTML = "OMG YOU'RE DONE";
        }
        totalTime--;    
    }


    

    function updateRest() {
        if (RestAfterS > 0) {
            interval3 = setInterval(RestCount, 5000);
        }
        else {
            startTime();
        }
    }
    
    function RestCount() {
        while (RestAfterS != 0) {
            RestAfterS--;
            PWR.innerHTML = "Set Rest!";
            textarea.innerHTML = RestAfterS;
        }
        j = 0;
        clearInterval(interval3);
    }




function stop(){
    timeRemaining = totalTime;
    timeonRemaining = timeon;
    timeoffRemaining = timeoff;
    RestRemaining = RestAfterS;
    ExercisesRemaining = OGExPS;
    setsRemaining = sets;
    clearTimeout(interval);
    // document.getElementById("Counter").innerHTML = j;
    

}
p {
    display: inline-flex;
    align-items: center;
}
label {
    float: left;
    display: block;
}
#userInput1 {
    display: flex;
    margin-bottom: 10px;
}

#userInput2 {
    display: flex;
    margin-bottom: 10px;
}

#userInput3 {
    display: flex;
    margin-bottom: 10px;
}

#userInput4 {
    display: flex;
    margin-bottom: 10px;
}

#userInput5 {
    display: flex;
    margin-bottom: 10px;
}

#Prepare {
    display: flex;
    margin-bottom: 10px;
}

#sets {
    display: flex;
    margin-bottom: 10px;
}

#timeon {
    display: flex;
    margin-bottom: 10px;
}

#timeoff {
    display: flex;
    margin-bottom: 10px;
}

#TotalTime {
    display: flex;
    margin-bottom: 10px;
}

#Counter {
    display: flex;
    margin-bottom: 10px;
}


input {
    height: 20px;
}

2 个答案:

答案 0 :(得分:2)

我想我对您要在这里完成的工作有一个大概的了解,但是如果我误解了任何内容,请告诉我。

假设您要执行一系列效果,并且它们之间要有一定的持续时间。为了使示例小,我们将使用console.log作为您要执行的任何效果的替代(例如,设置DOM元素的innerHTML)。

作为第一个示例,在这里我们等待1秒钟,显示“ Hello”,然后等待1.5秒,然后显示“ There”:

setTimeout(() => {
  console.log('Hello');
  setTimeout(() => {
    console.log('There');
  }, 1500);
}, 1000);

我们可以通过将通用部分描述为一个函数来阐明这一点:

function logAfter(message, delay, callback) {
  setTimeout(() => {
    console.log(message);
    if (callback) callback();
  }, delay);
}

那么我们的示例可以写成:

logAfter('Hello', 1000, () => {
  logAfter('There', 1500);
});

作为另一个可能与您的项目更相关的示例,这是我们如何创建可以多次执行效果的“循环”:

function logNAfter(message, times, delay, callback) {
  if (times === 0 && callback) {
    callback();
  }
  else {
    setTimeout(() => {
      console.log(message);
      logNAfter(message, times-1, delay, callback);
    }, delay);
  }
}

我们可以使用它来显示“嗨,那里!” 3次,每次相隔半秒,然后显示“再见!” 2秒后一次:

logNAfter('Hi There!', 3, 500, () => {
  logAfter('Goodbye!', 2000);
});

理论上,您可以以此方式创建任意长的适当间隔的效果序列。但是,我还应该提到,许多人宁愿将这些效果描述为Promise s

function logAfter(message, delay) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(message);
      resolve();
    }, delay);
  });
}

function logNAfter(message, times, delay) {
  if (times === 0) {
    return Promise.resolve();
  } else {
    return logAfter(message, delay)
      .then(() => logNAfter(message, times-1, delay));
  }
}

原始示例变为:

logAfter('Hello', 1000)
  .then(() => logAfter('There', 1500));

logNAfter('Hi There!', 3, 500)
  .then(() => logAfter('Goodbye!', 2000));

可以说,这只是对上面的回调样式方法的微小改进,但是如果您能够使用async/await,则更加清楚:

async function logAfter(message, delay) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(message);
      resolve();
    }, delay);
  });
}

async function logNAfter(message, times, delay) {
  for (let i = 0; i < times; ++i) {
    await logAfter(message, delay);
  }
}

async function demoSequence1() {
  await logAfter('Hello', 1000);
  await logAfter('There', 1500);
}

async function demoSequence2() {
  await logNAfter('Hi There!', 3, 500);
  await logAfter('Goodbye!', 2000);
}

希望有帮助!

答案 1 :(得分:0)

我喜欢Williams建议将其分解为不同的计时器,用户可以更容易地对其进行控制。但是,使用这种方法,我个人遇到了如何暂停计时器的问题。

我决定采用略有不同的方法。从给定的表中可以很清楚地看出如何设置计时器。计时器通常在整个锻炼期间在“锻炼时间”和“休息时间”之间交替。休息时间可以采用3个不同的值:

  1. 两次运动之间的最佳时间
  2. 组之间的最短时间
  3. 锻炼完成

由于输入这些值时所有这些值都是已知的,因此我的方法是在启动计时器之前设置计时器的过程。这会产生一点设置时间,但是我相信这是可以商定的,不会对性能造成重大影响。为此,我在启动计时器之前创建了一个创建的数组。此数组中的每个项目都包含数据,包括剩余总时间,当前设置,标签(锻炼或休息)以及标签计时器。创建此数组后,我们可以仅基于该数组中的项目数创建一个计时器。我希望这个小解释可以帮助您更好地理解我的解决方案。

Index.html

<!DOCTYPE html>
<html>
<style>
  td, th {
    text-align: left;
    padding: 8px;
  } 
</style>


<head>
  <title>Timer</title>
</head>


<body>
<!-- Inputs -->
<h2>Inputs</h2>
  <p>
    <label for="sets-input">Number of Sets: </label>
    <input type="number" id="sets-input" min="1" max="3600">
  </p>
  <p>
    <label for="exercises-input">Number of Exersizes per Set: </label>
    <input type="number" id="exercises-input" min="1" max="3600">
  </p>
  <p>
    <label for="workout-input">Exersise Time:  </label>
    <input type="number" id="workout-input" min="1" max="3600">
  </p>
  <p>
    <label for="exersiseRest-input">Rest between exersises: </label>
    <input type="number" id="exersiseRest-input" min="1" max="3600">
  </p>
  <p>
    <label for="setRest-input">Rest between Sets: </label>
    <input type="number" id="setRest-input" min="1" max="3600">
  </p>

<!-- Buttons -->
<p>
  <button id="start-button">Start</button>
  <button id="reset-button">Reset</button>
</p>


<!-- Timer Display  -->
  <h2>Outputs:</h2>
  <table>
    <tr>
      <th>Total Time Remaining: </th>
      <td id="timer-display">???</td>
    </tr> 
    <tr>
      <th>Set Number: </th>
      <td id="set-display">???</td>
    </tr> 
    <tr>
      <th id="label-display">???</th>
      <td id="labelTimer-display">???</td>
    </tr> 
    
  </table>

  <script src="tabada.js"></script>
</body>


</html>

Tabada.js

//-----------------------------------------------------------------------------------------------
// GLOBAL VARIABLES
//-----------------------------------------------------------------------------------------------

// HTML
var setsInput = document.getElementById("sets-input");
var exersisesInput = document.getElementById("exercises-input");
var workoutInput = document.getElementById("workout-input");
var exersiseRestInput = document.getElementById("exersiseRest-input");
var setRestInput = document.getElementById("setRest-input");

var timerDisplay = document.getElementById("timer-display");
var setDisplay = document.getElementById("set-display");
var labelDisplay = document.getElementById("label-display");
var labelTimerDisplay = document.getElementById("labelTimer-display");

var startButton = document.getElementById("start-button");
var resetButton = document.getElementById("reset-button");

// JavaScript
var sets = 2;
var exersises = 3;
var workout = 5;
var exersiseRest = 2;
var setRest = 3;

var totalTime = -1;
var myInterval = -1;
var tabadaArray = [];
var tabadaIndex = 0;


//-----------------------------------------------------------------------------------------------
// BUTTON FUNCTIONS
//-----------------------------------------------------------------------------------------------

// Start / Pause Button
startButton.addEventListener("click", function(event){

  // Set up Tabada Timer
  if (totalTime == -1){
    collectInputs();        // Comment this line for testing without inputs
    calculateTotalTime();
    createTabadaArray();
  }

  // Start timer
  if (myInterval == -1){
    startButton.innerHTML = "Pause";
    myInterval = setInterval(tabadaTimer, 1000);
  }

  // Pause timer
  else{
    startButton.innerHTML = "Start";
    clearInterval(myInterval);
    myInterval = -1
  }
});


// Reset Button
resetButton.addEventListener("click", function(event){
  
  // Stop Timer
  clearInterval(myInterval);   
 
  // Refresh Timer Display
  calculateTotalTime(); 
  updateOutputs(totalTime, 1, 'Workout', workout);               
  totalTime=-1;  // Alows user to change input values before clicking start button.

  // Reset start / pause button
  myInterval = -1;                  
  startButton.innerHTML = "Start"; 
});


//-----------------------------------------------------------------------------------------------
// SETUP FOR TABADA TIMER
//-----------------------------------------------------------------------------------------------

function collectInputs(){
  sets = parseFloat(setsInput.value);
  exersises = parseFloat(exersisesInput.value);
  workout = parseFloat(workoutInput.value);
  exersiseRest = parseFloat(exersiseRestInput.value);
  setRest = parseFloat(setRestInput.value);
}

function calculateTotalTime(){
  let totalWorkoutTime = workout * exersises * sets;
  let totalExersiseRest = exersiseRest * (exersises - 1) * sets;
  let totalSetsRest = setRest * (sets - 1);

  totalTime = totalWorkoutTime + totalExersiseRest + totalSetsRest;
}

function createTabadaArray() {
  tabadaIndex = 0;    // Global variable used for tabada timer
  tabadaArray = [];
  
  for( let set=1; set<=sets; set++ ){
    for( let exersise=1; exersise<=exersises; exersise++){

      // Workout
      addTimeBlock(set, 'Workout', workout);

      // Exersise Rest
      if ( exersise < exersises){
        addTimeBlock(set, 'Rest', exersiseRest);
      }

      // Set Rest
      else if( set < sets){
        addTimeBlock(set, 'Rest', setRest);
      }
      
      // Done
      else{break;}   // Very end exersize has no rest, so we must break the loop.
    }
  }
}

function addTimeBlock(set, label, labelTime) {

  // Add a sub timer to the array (workout, exersice rest, or set rest)
  for (let i=labelTime; i>0; i--) {
    tabadaArray.push({
      "totalTimeRemaining" : totalTime--,
      "set" : set,
      "label" : label,
      "labelTimeRemaining" : i,
    });
  }
}

//-----------------------------------------------------------------------------------------------
// TABADA TIMER
//-----------------------------------------------------------------------------------------------

function tabadaTimer(){
  // Still time left
  if (tabadaIndex < tabadaArray.length){
    let displayInfo = tabadaArray[tabadaIndex];
    updateOutputs(  displayInfo.totalTimeRemaining, 
                    displayInfo.set,
                    displayInfo.label,
                    displayInfo.labelTimeRemaining );
    tabadaIndex++;
  }

  // End of tabada timer
  else{
    clearInterval(myInterval);        // stop timer 
    updateOutputs(0, 1, 'Rest', 0);
    totalTime = -1
  }
}

function updateOutputs(totalTimeRemaining, setNumber, label, labelTimeRemaining){
  timerDisplay.innerHTML = convertSeconds(totalTimeRemaining);
  setDisplay.innerHTML = setNumber;
  labelDisplay.innerHTML = label;
  labelTimerDisplay.innerHTML = convertSeconds(labelTimeRemaining);
}

function convertSeconds(s){
  // Seconds -> mm:ss format 

  // Calculate
  let minutes = Math.floor(s/60);
  let seconds = s%60;

  // Format
  let formattedminutes = ("0" + minutes).slice(-2);
  let formattedseconds = ("0" + seconds).slice(-2);
  return formattedminutes + ':' + formattedseconds;
}