我如何共享我用js创建的倒数计时器?

How can I share a countDown timer I created with js?

我创建了一个倒计时计时器,效果很好。现在我想做的是,如果我离开网站,此事件不会刷新,并且还可以共享该事件……是否可以使用 js 来完成?或者我必须使用 NodeJS 吗?很抱歉密码是西班牙语。我想我可以使用 localstorage,但我以前从未使用过它。

let segundo = 1000,
  minuto = segundo * 60,
  hora = minuto * 60,
  dia = hora * 24;

let btnComenzar = document.querySelector("#comenzar");
let h3 = document.querySelector("h3");

//Generando el evento en base a la fecha actual.
function generarEvento() {
  let fechaEvento = document.querySelector("#fecha").value;
  let evento = new Date(fechaEvento).getTime(); //transformo la fecha ingresada a local time

  setInterval(() => {
    let fechaActual = new Date().getTime();
    //Calculo para llegar a la fecha del evento . 
    let cuentaRegresiva = evento - fechaActual;

    document.querySelector("#dia").innerText = Math.floor(cuentaRegresiva / dia);

    document.querySelector("#hora").innerText = Math.floor((cuentaRegresiva % dia) / hora);

    document.querySelector("#minuto").innerText = Math.floor((cuentaRegresiva % hora) / minuto);

    document.querySelector("#segundo").innerText = Math.floor((cuentaRegresiva % minuto) / segundo);

    //Cuando el contador llega a 0, genero el cartel de llegada/comienzo del evento
    if (cuentaRegresiva < 0) {
      h3.innerHTML = "¡Ha llegado el día!";
      let contador = document.querySelector(".contador");
      contador.style.display = "none"
    };

  });

};

function initApp() {
  //genero el click inicial
  btnComenzar.addEventListener("click", () => {
    h3.innerHTML = ` Su ${document.querySelector("#evento").value} comenzara en:`;
    generarEvento();

  });
}
initApp()
* {
  margin: 0;
  padding: 0;
  box-sizing: content-box;
}

body {
  font-family: 'Source Code Pro', monospace;
  background-image: url("https://i.pinimg.com/736x/14/42/04/144204bbc9b0963dddf3efb5e8b62162.jpg");
  background-repeat: no-repeat;
  background-size: 100%;
}

.container {
  width: 90%;
  margin: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-bottom: 25px;
}

.container h1 {
  margin: 50px;
}

h1,
h3 {
  text-align: center;
}

input {
  margin-left: 5px;
}

#evento {
  max-width: 290px;
  padding: 5px
}

#fecha {
  width: 130px;
}

button {
  width: 100px;
  padding: 5px;
  margin: 25px;
  align-self: center;
  border-radius: 10px;
  background-color: rgb(127, 150, 255);
  align-self: start;
}

.btnIcone {
  display: flex;
  flex-direction: row;
  justify-content: center;
}


/*Seccion invitacion*/

.invitaciones {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.invitaciones {
  display: none;
}

.invitaciones h4 {
  margin: 10px;
  padding: 10px;
}

input {
  width: 250px;
  margin: 10px;
}


/*Comienzo del contador*/

.container h3 {
  margin: 50px;
}

ul {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

li {
  list-style-type: none;
}

li span {
  font-size: 3rem;
  display: block;
}

footer {
  background-color: black;
  padding: 20px
}

hr {
  height: 100px;
  color: black;
}


/*Segunda parte de la pagina*/

.videoEjemplo {
  width: 100%;
  display: flex;
  flex-direction: row;
  margin: auto;
  justify-content: center;
  align-items: center;
}

.videoHijo {
  width: 100%;
  margin: auto;
  display: flex;
  flex-direction: column;
}

iframe {
  max-width: 550px;
  margin: 20px;
}

footer span {
  color: aliceblue;
  margin: auto;
}

@media screen and (max-width: 450px) {
  h1 {
    font-size: 1rem;
  }
  button {
    align-self: center;
  }
  iframe {
    width: 300px;
    margin: 0px;
    align-self: center;
  }
  .videoHijo span {
    font-size: 1.6rem;
    align-self: center;
  }
}

@media screen and (max-width:767px) {
  .videoEjemplo {
    flex-direction: column;
    justify-content: center;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!--Google Fonts-->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@1,600&display=swap" rel="stylesheet">
  <!--Font Awsome-->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer"
  />
  <!--Css propio-->
  <link rel="stylesheet" href="./css/style.css">
  <link rel="stylesheet" href="./css/modal.css">
  <title>Crea tu cuenta regresiva </title>
</head>

<body>
  <!--Seccion del modal-->
  <div class="modalBody">
    <div id="miModal" class="modal">
      <div class="contModal">
        <div class="modalHeader">
          <!--header del modal-->
          <span class="cerrar">&times;</span>
          <h2>Aviso</h2>
        </div>
        <!--fin header del modal-->
        <div class="cuerpoModal">
          <!--Cuerpo del modal-->
          <p>Por favor, no deje los campos vacíos.</p>
        </div>

      </div>
      <!--Fin "ContModal"-->
    </div>
    <!--Fin de "modal"-->
  </div>
  <!--Fin del modal-->







  <div class="container">
    <h1>Le damos la bienvenida a nuestro sitio donde va a poder crear su propia cuenta regresiva</h1>

    <label for="evento" class="evento">Ingrese el nombre de su evento </label>
    <input type="text" name="evento" id="evento" required><br>
    <label for="fecha">Ingrese la fecha del evento</label>
    <input type="datetime-local" name="fecha" id="fecha" required>

    <div class="btnIcon">
      <button type="submit" id="comenzar">Comenzar cuenta regresiva</button>
      <i class="fas fa-share-alt"> Compartir evento(proximamente)</i>
    </div>



    <div class="invitaciones">
      <h4> Crear lista de invitados (proximamente)</h4>
      <label for="nombreInvitado">Nombre del invitado: </label>
      <input type="text" name="nombreInvitado" id="nombreInvidado">
      <label for="email">Email del invitado: </label>
      <input type="email" name="email" id="email">
    </div>
  </div>

  <div class="container ">
    <h3>Su evento comenzará en</h3>
    <ul class="contador">
      <li><span id="dia"></span> Días</li>
      <li><span id="hora"></span> Horas</li>
      <li><span id="minuto"></span> Minutos</li>
      <li><span id="segundo"></span> Segundos</li>
    </ul>

  </div>

  <hr>
  <div class="container">
    <h3>Videos desde donde base mi código</h3>
    <div class="videoEjemplo">

      <div class="videoHijo">

        <span>Contador</span>
        <iframe height="315" src="https://www.youtube.com/embed/4k71G0tPJnA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
      </div>

      <div class="videoHijo">
        <span>Modal</span>
        <iframe height="315" src="https://www.youtube.com/embed/6ophW7Ask_0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
      </div>

    </div>
  </div>
  <footer>
    <span>Creado por Natacha Vergara</span>
  </footer>


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

</html>

Localstorage将数据保存到对象就像 key: string,因此您可以将日期保存为字符串。 然后您可以从该字符串创建新日期 -> 创建具有完全相同日期的新日期对象。

let d = new Date()
console.log(`original date: ${d.toLocaleDateString()}`)


function saveDate(date) {
    localStorage.myDate = date.toString()
}

function loadDate() {
    // savedDate will be <string> if 'myDate' exists in localStorage, otherwise it will be <undefined>
    const savedDate = localStorage.myDate
    return savedDate ? new Date(savedDate) : null
}


saveDate(d)

//-> date was saved to localStorage as 'myDate': <string>


// now create new date from that string
let d2 = loadDate()

console.log(`loaded date: ${d2.toLocaleDateString()}`)

因此,您的计时器应该做的第一件事是查看 localStorage 中是否有任何已保存的日期,如果没有则执行您的操作。

let date = loadDate() || `do some other stuff`

这将从本地存储字符串(如果有的话)创建一个日期并将其保存到变量 'date'。如果 localStorage 为空,它将在 ||

之后执行操作

如果你想试验.. 当你输入 F12 -> 控制台时:localStorage

... 它将向您显示该域的 localStorage。 您可以通过执行 localStorage.clear()

来清除它

一种方法是存储初始数据(姓名和日期):

//Generando el evento en base a la fecha actual.
function generarEvento() {
    let fechaEvento = document.querySelector("#fecha").value;
    let evento = new Date(fechaEvento).getTime();//transformo la fecha ingresada a local time

    setInterval(() => {
        let fechaActual = new Date().getTime();
        //Calculo para llegar a la fecha del evento . 
        let cuentaRegresiva = evento - fechaActual;

        document.querySelector("#dia").innerText = Math.floor(cuentaRegresiva / dia);

        document.querySelector("#hora").innerText = Math.floor((cuentaRegresiva % dia) / hora);

        document.querySelector("#minuto").innerText = Math.floor((cuentaRegresiva % hora) / minuto);

        document.querySelector("#segundo").innerText = Math.floor((cuentaRegresiva % minuto) / segundo);

        //Cuando el contador llega a 0, genero el cartel de llegada/comienzo del evento
        if (cuentaRegresiva < 0) {
            h3.innerHTML = "¡Ha llegado el día!";
            let contador = document.querySelector(".contador");
            contador.style.display = "none"
        };

        var obj = { 
            "name": document.querySelector("#evento").value, 
            "date": fechaEvento
        };
        localStorage.setItem("stored", JSON.stringify(obj));
    });

};

这些是已更改的相关行:

var obj = { 
    "name": document.querySelector("#evento").value, 
    "date": fechaEvento
};
localStorage.setItem("stored", JSON.stringify(obj));

这将创建一个很小的 ​​JSON 对象并将其存储在 localStorage 中。现在你只需要在页面加载时检查这个对象:

function initApp() {
    //genero el click inicial
    btnComenzar.addEventListener("click", () => {
        h3.innerHTML = ` Su ${document.querySelector("#evento").value} comenzara en:`;
        generarEvento();
    });

    let obj = JSON.parse(localStorage.getItem("stored"));
    if (obj) {
        document.querySelector("#evento").value = obj.name;
        document.querySelector("#fecha").value = obj.date;
        generarEvento();
    }

}

我自动将值放入文本框和日期选择器元素中。然后调用generarEvento()函数恢复定时器。

如果您不想使用 JSON 对象,您可以简单地单独存储日期和名称,或以逗号分隔(然后拆分以取回它们),或任何您希望的方式。由于对象很小,我不关心加载和保存时的 JSON.stringifyJSON.parse 开销。但是,如果您最终决定提供多个 countDown 而不是一个,这应该让您了解如何更新对象,只需将一组小对象存储在一个 localStorage 项中。