解决数字时钟按钮隐藏秒数后被setInterval重置的问题
数字时钟秒数显示状态持久化解决方案
我开发的数字时钟需要实现点击按钮切换秒数显示/隐藏的功能:点击后隐藏秒数,仅展示小时与分钟,再次点击恢复显示。目前点击按钮后秒数会暂时隐藏,但setInterval每次刷新时钟时都会自动恢复显示秒数,无法保持用户设置的状态。
原代码
JavaScript代码
window = onload = function () { function displayTime(dataObject) { const displayDate = document.getElementById('date-elements'); const displayTime = document.getElementById('time-elements'); const parts = { //date elements: weekday: dataObject.getDay(), daysNumber: dataObject.getDate(), month: dataObject.getMonth() + 1, year: dataObject.getFullYear(), //time elements: hours: dataObject.getHours(), minutes: dataObject.getMinutes(), seconds: dataObject.getSeconds(), }; const formatAMPM = parts.hours >= 12 ? "PM" : "AM"; const dayState = formatAMPM; parts.hours = parts.hours % 12; parts.hours ? parts.hours : 12; //appending zero if smaller than 10 dysNmbr = parts.daysNumber < 10 ? "0" + parts.daysNumber : parts.daysNumber; mnth = parts.month < 10 ? "0" + parts.month : parts.month; hrs = parts.hours < 10 ? "0" + parts.hours : parts.hours; mins = parts.minutes < 10 ? "0" + parts.minutes : parts.minutes; secs = parts.seconds < 10 ? "0" + parts.seconds : parts.seconds; //array of weekdays names days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ]; //determine the weekday currentDayName = days[parts.weekday]; displayDate.innerHTML = `${currentDayName}, ${dysNmbr}.${mnth}.${parts.year}`; displayTime.innerHTML = `${hrs} : ${mins} : ${secs} ${dayState}`; const btn = document.getElementById("btn"); btn.addEventListener("click", () => { displayTime.innerHTML = `${hrs} : ${mins} ${dayState}` }) } let currentDate = new Date(); let formattedDate = displayTime(currentDate); setInterval(() => { currentDate = new Date(); formattedDate = displayTime(currentDate); formattedDate; }, 10); };
HTML代码
<body> <div id="date-elements"></div> <div id="time-elements"></div> <button id="btn">Display seconds</button> </body>
问题根源
- 无状态变量记录用户选择的显示模式,每次
displayTime执行都会强制渲染带秒数的格式,覆盖按钮修改 - 按钮事件监听被放在
displayTime函数内部,每次刷新都会重复绑定事件,造成性能浪费 - 原代码中
parts.hours ? parts.hours : 12未赋值,导致12小时制转换无效
修复方案
- 在
onload作用域内声明状态变量showSeconds,初始值为true(默认显示秒数) - 将按钮事件监听移出
displayTime函数,仅绑定一次 - 点击按钮时切换
showSeconds状态,并同步更新按钮文字提示 - 在
displayTime中根据showSeconds的状态决定渲染的时间格式
修改后的完整代码
JavaScript代码
window.onload = function () { // 状态变量:记录是否显示秒数 let showSeconds = true; const displayDate = document.getElementById('date-elements'); const displayTime = document.getElementById('time-elements'); const btn = document.getElementById("btn"); // 按钮点击事件:切换显示状态 btn.addEventListener("click", () => { showSeconds = !showSeconds; // 更新按钮文字 btn.textContent = showSeconds ? "Hide seconds" : "Display seconds"; // 立即刷新时间显示 displayTime(new Date()); }); function displayTime(dataObject) { const parts = { weekday: dataObject.getDay(), daysNumber: dataObject.getDate(), month: dataObject.getMonth() + 1, year: dataObject.getFullYear(), hours: dataObject.getHours(), minutes: dataObject.getMinutes(), seconds: dataObject.getSeconds(), }; const formatAMPM = parts.hours >= 12 ? "PM" : "AM"; const dayState = formatAMPM; // 修复12小时制转换:赋值给parts.hours parts.hours = parts.hours % 12; parts.hours = parts.hours ? parts.hours : 12; // 补零处理,使用let声明变量避免全局污染 let dysNmbr = parts.daysNumber < 10 ? "0" + parts.daysNumber : parts.daysNumber; let mnth = parts.month < 10 ? "0" + parts.month : parts.month; let hrs = parts.hours < 10 ? "0" + parts.hours : parts.hours; let mins = parts.minutes < 10 ? "0" + parts.minutes : parts.minutes; let secs = parts.seconds < 10 ? "0" + parts.seconds : parts.seconds; const days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ]; const currentDayName = days[parts.weekday]; displayDate.innerHTML = `${currentDayName}, ${dysNmbr}.${mnth}.${parts.year}`; // 根据状态变量决定显示格式 if (showSeconds) { displayTime.innerHTML = `${hrs} : ${mins} : ${secs} ${dayState}`; } else { displayTime.innerHTML = `${hrs} : ${mins} ${dayState}`; } } // 初始化显示 displayTime(new Date()); // 每秒刷新一次(原10毫秒太频繁,改为1000毫秒更合理) setInterval(() => { displayTime(new Date()); }, 1000); };
HTML代码
<body> <div id="date-elements"></div> <div id="time-elements"></div> <button id="btn">Hide seconds</button> </body>
额外优化点
- 将
setInterval间隔从10毫秒改为1000毫秒,避免不必要的性能消耗 - 使用
let/const声明变量,避免全局变量污染 - 修复12小时制转换的赋值问题
- 按钮文字随状态切换,提升用户体验
内容的提问来源于stack exchange,提问作者madara030
相关产品推荐
相关产品推荐

