如何停止计时器计数并从节省的时间开始

问题描述

我对编程有点陌生,但是最近我尝试做我的第一个小项目叫计时器计数,这只是一个简单的本地网站,当我决定在白天开始编程时,我会打开它,并且计数时间。我创建了具有2个不同功能(启动,停止)的2个按钮,但是我遇到的问题是我不知道如何实现停止功能。这个想法是计时器应该在单击按钮后停止,而当我单击开始按钮时,它应该从节省的时间开始。 这是HTML / CSS代码

   <div class="timer-display-id"> 
    <h1>Timer </h1>
    <p id="timer">00:00:00 </p>
     <button id="start-timer" onclick="start()">Start </button>
      <button id="stop-timer" onclick="stop()">Stop  </button>
  </div>
  <script src="timer.js"></script>

这是JS代码

function stop() {
     // not exactly sure if this function should be here,anyway no idea what to add to get this to work
    clearInterval(interval);
    start.disabled = false;
  }
function convertSec(cnt) {
   let sec = cnt % 60;
   let min = Math.floor(cnt / 60);
   if (sec < 10) {
      if (min < 10) {return "0" + min + ":0" + sec;}
      else          {return min + ":0" + sec;}
     }
   else if ((min < 10) && (sec >= 10)) {return "0" + min + ":" + sec;}
   else {return min + ":" + sec;}
  }

function start() {
  
   let ret = document.getElementById("timer");
   let counter = 0;
   let start = document.querySelector("#start-timer");
   let stop = document.querySelector("#stop-timer");
   start.disabled = true;
   let interval = setInterval(function() {
     ret.innerHTML = convertSec(counter++); // timer start counting here...

    },1000);
  
}

我知道这可能非常混乱,缺乏逻辑,但是我现在最好能做到。如果您想提供有关代码组织的一些技巧,我将不胜感激。

解决方法

在拥有defmodule MyApp.Plug.PublicIp do @moduledoc "Get public IP address of request from x-forwarded-for header" @behaviour Plug @app :my_app def init(opts),do: opts def call(%{assigns: %{ip: _}} = conn,_opts),do: conn def call(conn,_opts) do process(conn,Plug.Conn.get_req_header(conn,"x-forwarded-for")) end def process(conn,[]) do Plug.Conn.assign(conn,:ip,to_string(:inet.ntoa(get_peer_ip(conn)))) end def process(conn,vals) do if Application.get_env(@app,:trust_x_forwarded_for,false) do ip_address = get_ip_address(conn,vals) # Rewrite standard remote_ip field with value from header # See https://hexdocs.pm/plug/Plug.Conn.html conn = %{conn | remote_ip: ip_address} Plug.Conn.assign(conn,to_string(:inet.ntoa(ip_address))) else Plug.Conn.assign(conn,to_string(:inet.ntoa(get_peer_ip(conn)))) end end defp get_ip_address(conn,vals) defp get_ip_address(conn,[]),do: get_peer_ip(conn) defp get_ip_address(conn,[val | _]) do # Split into multiple values comps = val |> String.split(~r{\s*,\s*},trim: true) |> Enum.filter(&(&1 != "unknown")) # Get rid of "unknown" values |> Enum.map(&(hd(String.split(&1,":")))) # Split IP from port,if any |> Enum.filter(&(&1 != "")) # Filter out blanks |> Enum.map(&(parse_address(&1))) # Parse address into :inet.ip_address tuple |> Enum.filter(&(is_public_ip(&1))) # Elminate internal IP addreses,e.g. 192.168.1.1 case comps do [] -> get_peer_ip(conn) [comp | _] -> comp end end @spec get_peer_ip(Plug.Conn.t) :: :inet.ip_address defp get_peer_ip(conn) do {ip,_port} = conn.peer ip end @spec parse_address(String.t) :: :inet.ip_address defp parse_address(ip) do case :inet.parse_ipv4strict_address(to_charlist(ip)) do {:ok,ip_address} -> ip_address {:error,:einval} -> :einval end end # Whether the input is a valid,public IP address # http://en.wikipedia.org/wiki/Private_network @spec is_public_ip(:inet.ip_address | atom) :: boolean defp is_public_ip(ip_address) do case ip_address do {10,_,_} -> false {192,168,_} -> false {172,second,_} when second >= 16 and second <= 31 -> false {127,_} -> false {_,_} -> true :einval -> false end end end 函数的同时,两个函数都可以访问interval,只需将其移到setInterval函数之外即可:

start
const ret = document.getElementById("timer");
const startBtn = document.querySelector("#start-timer");

let counter = 0;
let interval;

function stop() {
  clearInterval(interval);
  startBtn.disabled = false;
}

function convertSec(cnt) {
  let sec = cnt % 60;
  let min = Math.floor(cnt / 60);
  if (sec < 10) {
    if (min < 10) {
      return "0" + min + ":0" + sec;
    } else {
      return min + ":0" + sec;
    }
  } else if ((min < 10) && (sec >= 10)) {
    return "0" + min + ":" + sec;
  } else {
    return min + ":" + sec;
  }
}

function start() {
  startBtn.disabled = true;
  interval = setInterval(function() {
    ret.innerHTML = convertSec(counter++); // timer start counting here...
  },1000);
}

,

如果您希望在点击“停止”后保存计数并从同一点重新开始,则需要在count函数外部的某个位置定义start()变量,这样它可以告诉您重新开始计数的次数。目前,countstart()函数的本地函数,它将每次将其重置为零。

通过使用1秒间隔计时器更新计数,您的计数器会将每个时间段舍入为整秒。这样做会稍微复杂一些,但是如果您希望能够将多个计数中的部分秒数相加,使用类似Date.getTime()的方法来记录按下开始按钮的时间会更准确,然后检查stop()触发时所经过的时间,并将其添加到您的计数中。但是,您可能仍想使用间隔计时器定期更新当前值。同样,您需要检查要使用的变量的作用域是否正确,以便使用它们的函数可以看到它们,并且在函数调用之间不会丢失它们。