You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决数字时钟按钮隐藏秒数后被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>

问题根源

  1. 无状态变量记录用户选择的显示模式,每次displayTime执行都会强制渲染带秒数的格式,覆盖按钮修改
  2. 按钮事件监听被放在displayTime函数内部,每次刷新都会重复绑定事件,造成性能浪费
  3. 原代码中parts.hours ? parts.hours : 12未赋值,导致12小时制转换无效

修复方案

  1. 在onload作用域内声明状态变量showSeconds,初始值为true(默认显示秒数)
  2. 将按钮事件监听移出displayTime函数,仅绑定一次
  3. 点击按钮时切换showSeconds状态,并同步更新按钮文字提示
  4. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:45:31