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

自动登出应用计时器重置故障:mousemove事件绑定后功能无法正常运行

问题原因分析
  • 定时器未清理:你在initializeClock函数内部定义的timeinterval定时器ID是局部变量,每次调用函数生成的新定时器没法覆盖/销毁之前的旧定时器,多个定时器同时运行会导致倒计时显示异常、重置逻辑失效
  • 事件频繁触发:mousemove事件每秒会触发几十次,没有防抖的情况下会短时间内创建大量定时器,进一步加剧逻辑混乱
修复后的完整代码

CSS部分(无需修改可直接复用)

body{
    text-align: center;
    background: #00ECB9;
    font-family: sans-serif;
    font-weight: 100;
  }
  
  h1{
    color: #396;
    font-weight: 100;
    font-size: 40px;
    margin: 40px 0px 20px;
  }
  
  #clockdiv{
    font-family: sans-serif;
    color: #fff;
    display: inline-block;
    font-weight: 100;
    text-align: center;
    font-size: 30px;
  }
  
  #clockdiv > div{
    padding: 10px;
    border-radius: 3px;
    background: #00BF96;
    display: inline-block;
  }
  
  #clockdiv div > span{
    padding: 15px;
    border-radius: 3px;
    background: #00816A;
    display: inline-block;
  }
  
  .smalltext{
    padding-top: 5px;
    font-size: 16px;
  }

HTML+JS部分(核心逻辑修复)

<!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">
    <link href="styles/styles.css" rel="stylesheet">
    <title>Document</title>
</head>
<body>
    <a href="infoPage.html">Info Page</a>
    <h1>Countdown Clock</h1>
    <div id="clockdiv">
        <div>
            <span class="days"></span>
            <div class="smalltext">Days</div>
        </div>
        <div>
            <span class="hours"></span>
            <div class="smalltext">Hours</div>
        </div>
        <div>
            <span class="minutes"></span>
            <div class="smalltext">Minutes</div>
        </div>
        <div>
            <span class="seconds"></span>
            <div class="smalltext">Seconds</div>
        </div>
    </div>
    <script>
        // 全局存储定时器ID,方便后续清理
        let timeinterval = null
        // 防抖定时器,避免mousemove高频触发重置逻辑
        let debounceTimer = null
        // 倒计时时长设为常量,减少冗余赋值
        const COUNT_DOWN_MINUTES = 10

        function getTimeRemaining(endtime) {
            const total = Date.parse(endtime) - Date.parse(new Date());
            const seconds = Math.floor((total / 1000) % 60);
            const minutes = Math.floor((total / 1000 / 60) % 60);
            const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
            const days = Math.floor(total / (1000 * 60 * 60 * 24));
            return {
                total,
                days,
                hours,
                minutes,
                seconds
            };
        }

        function initializeClock(id, endtime) {
            // 初始化前先清理上一个定时器,确保仅单定时器运行
            if (timeinterval) clearInterval(timeinterval)
            const clock = document.getElementById(id);
            const daysSpan = clock.querySelector('.days');
            const hoursSpan = clock.querySelector('.hours');
            const minutesSpan = clock.querySelector('.minutes');
            const secondsSpan = clock.querySelector('.seconds');

            function updateClock() {
                const t = getTimeRemaining(endtime);
                daysSpan.innerHTML = t.days;
                hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
                minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
                secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
                if (t.total <= 0) {
                    clearInterval(timeinterval);
                    // 此处可添加自动登出的业务逻辑
                }
            }
            updateClock();
            timeinterval = setInterval(updateClock, 1000);
        }

        // 首次初始化倒计时
        let deadline = new Date(Date.parse(new Date()) + COUNT_DOWN_MINUTES * 60 * 1000);
        initializeClock('clockdiv', deadline);

        // 带防抖的重置逻辑,300ms内多次触发仅执行最后一次
        function resetTimer() {
            clearTimeout(debounceTimer)
            debounceTimer = setTimeout(() => {
                deadline = new Date(Date.parse(new Date()) + COUNT_DOWN_MINUTES * 60 * 1000);
                initializeClock('clockdiv', deadline);
            }, 300)
        }
        window.addEventListener("mousemove", resetTimer);
        // 可按需补充其他用户活跃事件的监听,覆盖更多场景
        // window.addEventListener("click", resetTimer);
        // window.addEventListener("keydown", resetTimer);
    </script>
</body>
</html>
改动说明
  • 全局存储定时器ID,每次初始化前先清理旧定时器,避免多定时器并行导致的显示异常
  • 增加防抖逻辑,解决mousemove高频触发带来的性能问题和逻辑混乱,防抖阈值可根据实际需求调整
  • 固定倒计时时长为常量,减少重复赋值的冗余代码
  • 预留了其他用户活跃事件的监听入口,可根据需求添加点击、键盘输入等场景的重置触发

内容的提问来源于stack exchange,提问作者Kaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:54:06