JS - 如何为我的秒表编写时间限制功能?

Posted

技术标签:

【中文标题】JS - 如何为我的秒表编写时间限制功能?【英文标题】:JS - How to write a time limit function for my stopwatch? 【发布时间】:2022-01-09 11:18:40 【问题描述】:

我正在尝试创建秒表,但我希望能够为我的秒表停止运行添加时间限制。有没有办法我可以做到这一点?并且还创建了一个单击停止以指示时间停止的函数。

下面是我现在的代码。

let offset = 0,
  paused = true;

render();

function startStopwatch(evt) 
  if (paused) 
    paused = false;
    offset -= Date.now();
    render();
  


function stopStopwatch(evt) 
  if (!paused) 
    paused = true;
    offset += Date.now();
  


function resetStopwatch(evt) 
  if (paused) 
    offset = 0;
    render();
   else 
    offset = -Date.now();
  


function format(value, scale, modulo, padding) 
  value = Math.floor(value / scale) % modulo;
  return value.toString().padStart(padding, 0);


function render() 
  var value = paused ? offset : Date.now() + offset;

  document.querySelector('#s_ms').textContent = format(value, 1, 1000, 3);
  document.querySelector('#s_seconds').textContent = format(value, 1000, 60, 2);
  document.querySelector('#s_minutes').textContent = format(value, 60000, 60, 2);
  document.querySelector('#s_hours').textContent = format(value, 3600000, 24, 2);
  if (!paused) 
    requestAnimationFrame(render);
  

【问题讨论】:

只需检查 if (value > limit) 并停止渲染周期(和/或将其设置为 paused 或其他内容) 【参考方案1】:

我对使用requestAnimationFrame 作为秒表的想法很感兴趣, 所以我做了我的测试... 如果您有任何问题,它是开放的!

const 
  btStart = document.querySelector('#bt-start')
, btReset = document.querySelector('#bt-reset')
, zChrono = document.querySelector('#z-chrono')
, ui      = (function( chronoZone = zChrono, timOutStrEvt = 'time_out' )
    
    const 
      one_Sec = 1000
    , one_Min = one_Sec * 60
    , one_Hrs = one_Min * 60
    , one_Day = one_Hrs * 24
    , SMHD    = [ one_Sec, one_Min, one_Hrs, one_Day ]
    , n_Dgts  = (n,t) => (`0`.repeat(n)+t.toString(10)).slice(-n)
    , timeOut = new Event( timOutStrEvt )
      ;
    let timeLimit = 0
      ;
    return 
      setTimeLimit(...t)
        
        if (t.length > SMHD.length)  t.length = 0
        timeLimit = t.reverse().reduce((l,v,i)=>l+(v*SMHD[i]),0)
        
    , setTimeLimit_ms(...t)
        
        if (t.length > (SMHD.length+1))  t.length = 0
        let ms = t.pop() || 0
        timeLimit = t.reverse().reduce((l,v,i)=>l+(v*SMHD[i]), ms)
        
    , setChrono(tim)
        
        let
          timOut = !!timeLimit ? (tim >= timeLimit) : false
        , t_H    = n_Dgts(2,Math.floor(tim / one_Hrs))
        , t_M    = n_Dgts(2,Math.floor((tim % one_Hrs) / one_Min))
        , t_S    = n_Dgts(2,Math.floor((tim % one_Min) / one_Sec))
          ;           
        chronoZone.textContent = `$t_H:$t_M:$t_S.$n_Dgts(3,tim)`

        if (timOut) chronoZone.dispatchEvent(timeOut)

        return timOut
        
    
  )()
, chrono  = (function( showChrono = ui.setChrono )
    
    let startTime   = null
      , timeElapsed = 0
      , pausedTime  = 0
      , reqRef      = null
      , reqPause    = false
      , stoped      = false
      ;
    function reqLoop(timeStamp)
      
      startTime ??= timeStamp  // Logical nullish assignment (??=)

      if (stoped)
        
        cancelAnimationFrame(reqRef)
        return
        
      if (reqPause) 
         
        pausedTime = (timeStamp - startTime) - timeElapsed;
        
      else
        
        timeElapsed = parseInt((timeStamp - startTime) - pausedTime)
        reqPause    = showChrono(timeElapsed)
        
      requestAnimationFrame( reqLoop )
      
    return  
      start()       reqRef   = requestAnimationFrame(reqLoop) 
    , pause(OnOff)  reqPause = OnOff 
    , stop()        stoped   = true  
    , RaZ()
        
        startTime   = null
        timeElapsed = 0
        pausedTime  = 0
        reqRef      = null
        reqPause    = false
        stoped      = false
        
      
    )()
  ; // constants ending

ui.setChrono(0)  // user interface init...

// ---------------------------------------------- time Limit addition 
const sTimeLimit = document.querySelector('#sl-timeLimit')
sTimeLimit.selectedIndex = 0

sTimeLimit.onchange =_=>
  
  switch (sTimeLimit.value )
    
    case '0':     ui.setTimeLimit(0);        break;
    case '5':     ui.setTimeLimit(5);        break;
    case '23':    ui.setTimeLimit(23);       break;
    case '2:4':   ui.setTimeLimit(2,4);      break;
    case '1:2:3': ui.setTimeLimit(1,2,3);    break;
    case '1.456': ui.setTimeLimit_ms(1,456); break;
   
// ------------------------------------- time Limit addition ending

btStart.onclick =_=>
  
  switch (btStart.textContent)
    
    case 'start':
      chrono.RaZ()
      chrono.start()
      btStart.textContent = 'pause'
      break;
    case 'pause':
      chrono.pause(true)
      btStart.textContent = 'continue'
      break;
    case 'continue':
      chrono.pause(false)
      btStart.textContent = 'pause'
      break;
    
  
btReset.onclick =_=>
  
  chrono.stop()
  ui.setChrono( 0 )
  btStart.textContent = 'start'
  btStart.disabled    = false 
  
zChrono.addEventListener('time_out',()=>
  
  btStart.disabled    = true 
  chrono.stop()
  alert (`Time limit elapsed >= $sTimeLimit.selectedOptions[0].textContent.trim()`)
  )
body 
  font-family: Arial, Helvetica, sans-serif;
  
button 
  width          : 6em;
  text-transform : capitalize;
  
h2 
  padding : 0 2em;
  color   : darkblue;
  
<button id="bt-start" >start</button>
<button id="bt-reset" >reset</button>
<select id="sl-timeLimit">
  <option value="" selected disabled> set time limit..?</option>
  <option value="0"     > no time limit               </option>
  <option value="5"     > 5 seconds                  </option>
  <option value="23"    > 23 seconds                 </option>
  <option value="2:4"   > 2 minutes & 4 seconds      </option>
  <option value="1:2:3" > 1 hour 2 minutes 3 seconds </option>
  <option value="1.456" > 1s 456 ms                 </option>
</select>
<h2 id="z-chrono">00-------</h2>

【讨论】:

@Bergi 你对我的回答有意见吗?

以上是关于JS - 如何为我的秒表编写时间限制功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何为我的 django 应用程序编写注销功能?

你会如何为失明的人设计一款钟表?(大众点评-2014)

如何为sails.js 编写模块

如何为 Discord 网关设置心跳功能

带有单圈时间的秒表 JavaScript(如 iPhone 秒表)

如何为我的 Discord.js 机器人编写事件/命令处理程序?