JS自定义倒计时如何实现离站不重置及事件分享 是否需用NodeJS
需求实现方案说明
1. 本地持久化(用户离开站点返回后倒计时不重置)
这个需求完全可以仅通过前端JavaScript实现,你的推测正确,使用localStorage就能实现该功能。localStorage是浏览器原生提供的本地存储API,存储的数据不会随页面关闭、浏览器退出而丢失,基础用法非常简单:
- 存数据:
localStorage.setItem('自定义键名', '待存储内容'),如果要存对象可以先用JSON.stringify()转为字符串 - 读数据:
localStorage.getItem('自定义键名'),如果是对象可以用JSON.parse()转回原格式 - 删数据:
localStorage.removeItem('自定义键名')
2. 倒计时事件分享给其他用户
这个需求也可以通过纯前端方案实现,不需要用到Node.js:
- 纯前端方案:将事件名称、事件时间编码到URL的查询参数中,用户点击分享时直接复制带参数的链接,其他用户打开链接时前端直接读取URL参数即可渲染对应倒计时,全程不需要后端参与
- 需要Node.js的场景:只有当你需要实现短链接转换、存储大量历史事件、统计分享访问量、发送邮件邀请这类进阶功能时,才需要用到Node.js开发后端接口存储数据
适配需求的修改后核心JS代码
兼容你原有的西班牙语变量命名,已经内置本地持久化+URL分享功能:
let segundo = 1000, minuto = segundo * 60, hora = minuto * 60, dia = hora * 24; let btnComenzar = document.querySelector("#comenzar"); let h3 = document.querySelector("h3"); let timer = null; // 存储定时器ID,避免重复生成定时器 // 抽离公共倒计时渲染逻辑 function renderizarContador(nombreEvento, timestampEvento) { h3.innerHTML = ` Su ${nombreEvento} comenzara en:`; // 清除之前运行的定时器 if(timer) clearInterval(timer); timer = setInterval(() => { let fechaActual = new Date().getTime(); let cuentaRegresiva = timestampEvento - fechaActual; if (cuentaRegresiva < 0) { h3.innerHTML = "¡Ha llegado el día!"; document.querySelector(".contador").style.display = "none"; clearInterval(timer); // 倒计时到期后清除本地存储 localStorage.removeItem('eventoGuardado'); return; } 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); }, 1000); // 补充原代码缺失的定时器间隔,每秒刷新一次 } // 分享链接生成逻辑,点击分享按钮时调用即可 function generarLinkCompartir(nombreEvento, fechaEvento) { const params = new URLSearchParams(); params.set('nombre', encodeURIComponent(nombreEvento)); params.set('fecha', fechaEvento); const linkCompartir = `${window.location.origin}${window.location.pathname}?${params.toString()}`; // 自动复制链接到剪贴板 navigator.clipboard.writeText(linkCompartir).then(() => { alert('分享链接已复制到剪贴板!'); }); } function generarEvento() { let nombreEvento = document.querySelector("#evento").value; let fechaEvento = document.querySelector("#fecha").value; let evento = new Date(fechaEvento).getTime(); // 将事件存储到本地 const eventoGuardado = { nombre: nombreEvento, fecha: fechaEvento, timestamp: evento }; localStorage.setItem('eventoGuardado', JSON.stringify(eventoGuardado)); renderizarContador(nombreEvento, evento); // 需要生成分享链接时取消下一行注释即可 // generarLinkCompartir(nombreEvento, fechaEvento); } function initApp() { // 优先读取URL中的分享参数,适配其他用户打开分享链接的场景 const params = new URLSearchParams(window.location.search); const nombreShare = params.get('nombre'); const fechaShare = params.get('fecha'); if(nombreShare && fechaShare) { const timestampShare = new Date(decodeURIComponent(fechaShare)).getTime(); renderizarContador(decodeURIComponent(nombreShare), timestampShare); return; } // 读取本地存储的事件,适配用户返回站点的场景 const eventoGuardado = localStorage.getItem('eventoGuardado'); if(eventoGuardado) { const {nombre, timestamp} = JSON.parse(eventoGuardado); renderizarContador(nombre, timestamp); return; } // 没有存储内容时走点击创建逻辑 btnComenzar.addEventListener("click", () => { // 此处可补充你原有的表单非空校验逻辑,校验通过后再调用generarEvento generarEvento(); }); } initApp()
内容的提问来源于stack exchange,提问作者Natacha Vergara
相关产品推荐
相关产品推荐

